SlideShare a Scribd company logo
1 of 33
問題3 夜店(Night Market)
                  山下 洋史
問題のおさらい
•   N個の夜店のなかから順番通りにいくつか選んで遊ぶ
•   夜店で遊べる時間はTだけ
•   遊んでいる時間が時刻Sに被ってはいけない
•   楽しさの合計を最大にする                  花火




     夜店1               8       楽しさの合計M=8+2+6=16
     夜店2       2

     夜店3                   7

     夜店4   6

     夜店5           5
問題のおさらい
•   N個の夜店のなかから順番通りにいくつか選んで遊ぶ
•   夜店で遊べる時間はTだけ
•   遊んでいる時間が時刻Sに被ってはいけない
•   楽しさの合計を最大にする              花火


           8           2           6

     夜店1                   楽しさの合計M=8+2+6=16
     夜店2

     夜店3           7

     夜店4

     夜店5       5
まずは力技で
•   とりあえず全通り選んでみて入れてみる

                    8                      8


            2                      2


                        7                      7


        6                      6


                5                      5




    •       N=20なら2^20=約1000000(10^6)通り試せばできる
まずは力技で
•   とりあえず全通り選んでみて入れてみる
                 8   2

                         7
                                               8


                             失敗!       2


                                                   7


        6                          6


             5                             5




    •       N=20なら2^20=約1000000(10^6)通り試せばできる
まずは力技で
•   とりあえず全通り選んでみて入れてみる
                 8   2                         7      6

                         7


                                                   M=7+6=13
                                           8


                             失敗!   2




        6


             5                         5




    •       N=20なら2^20=約1000000(10^6)通り試せばできる
まずは力技で
•   とりあえず全通り選んでみて入れてみる
                  8   2                         7      6

                          7


                                                    M=7+6=13
                                            8


                              失敗!   2




        6


              5                         5




  N=20なら2^20=約1000000(10^6)通り試せばできる
    •
• N=3000なら2^3000=100......................00(10^900ぐらい)も!
•           10%以上の得点は無理そう…
•           O(2^N)
とりあえず10点
もしも花火が到着の瞬間に打ち上がったら
     花火




      夜店1               8

      夜店2       2

      夜店3                   7

      夜店4   6

      夜店5           5


•   花火大会がなくなったのと同じ状況
•   ちょっと簡単になった.でもどうしよう?
もしも花火が到着の瞬間に打ち上がったら
     花火




      夜店1               8

      夜店2       2

      夜店3                   7

      夜店4   6

      夜店5           5


•   花火大会がなくなったのと同じ状況
•   ちょっと簡単になった.でもどうしよう?
→動的計画法(DP)が使える
動的計画法(DP)って何さ
•   おなじみの人にはおなじみDynamic Programming
•   ある最適化問題を複数の部分問題に分割して解く際に、そこまでに求められている以上
    の最適解が求められないような部分問題を切り捨てながら解いていく手法である。
    (Wikipediaより)

•   100番目のフィボナッチ数(1,1,2,3,5,8,...)の計算で例える
    •   k番目までのフィボナッチ数が分かっていた(部分問
        題)ら,k-1番目の物とk番目の物を足せばk+1番目の
        ものが分かる
    •   これを繰り返すと100番目のフィボナッチ数がわかる
•   途中まで計算した結果を用いて次の計算をする
ナップサック問題
•   動的計画法(DP)の典型的な応用例
•   ナップサックに,いろんな体積と値段の荷物を入れる
•   荷物の体積の合計をナップサックの体積以下にしなが
    ら,値段の合計を出来るだけ大きくする
      ナップサック問題                            今回の問題(S=0の場合)


                                          8
              8       5
                                  2

                                              7
          2               6
                  7           6

                                      5




                          一緒!
やってみよう
•   時刻 t までに,夜店 i までを遊ぶときの楽しさの最高をもと
    める(その答えをdp(t,i)と置いておきます)
•   dp(t,i+1)を求めたい
    •   夜店 i+1 で遊ぶ
        →時刻(t - Bi+1)で夜店 i まで遊んだ時の楽しさ + Ai+1
    •   夜店i+1で遊ばない
        →時刻 t で夜店 i まで遊んだ時の楽しさ
•   この二つの大きい方を取る!
表を埋める
•   dp(t,i+1)=下の2つのmax
    •   夜店 i+1 で遊ぶ→時刻(t - Bi+1)で夜店 i まで遊んだ時の楽しさ + Ai+1
    •   夜店i+1で遊ばない→時刻 t で夜店 i まで遊んだ時の楽しさ
•   数式で書くとdp(t , i+1)=max{dp(t - Bi+1, i) + Ai+1 , dp(t,i)}

    dp 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

    1 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8 8 8 8 8

    2 0 0 0 0

    3

    4              A2=2,B2=4

    5
表を埋める
•   dp(t,i+1)=下の2つのmax
    •   夜店 i+1 で遊ぶ→時刻(t - Bi+1)で夜店 i まで遊んだ時の楽しさ + Ai+1
    •   夜店i+1で遊ばない→時刻 t で夜店 i まで遊んだ時の楽しさ
•   数式で書くとdp(t , i+1)=max{dp(t - Bi+1, i) + Ai+1 , dp(t,i)}

    dp 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

    1 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8 8 8 8 8

    2 0 0 0 0 2

    3

    4              A2=2,B2=4

    5
表を埋める
•   dp(t,i+1)=下の2つのmax
    •   夜店 i+1 で遊ぶ→時刻(t - Bi+1)で夜店 i まで遊んだ時の楽しさ + Ai+1
    •   夜店i+1で遊ばない→時刻 t で夜店 i まで遊んだ時の楽しさ
•   数式で書くとdp(t , i+1)=max{dp(t - Bi+1, i) + Ai+1 , dp(t,i)}

    dp 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

    1 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8 8 8 8 8

    2 0 0 0 0 2 2 2 2 2

    3

    4              A2=2,B2=4

    5
表を埋める
•   dp(t,i+1)=下の2つのmax
    •   夜店 i+1 で遊ぶ→時刻(t - Bi+1)で夜店 i まで遊んだ時の楽しさ + Ai+1
    •   夜店i+1で遊ばない→時刻 t で夜店 i まで遊んだ時の楽しさ
•   数式で書くとdp(t , i+1)=max{dp(t - Bi+1, i) + Ai+1 , dp(t,i)}

    dp 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

    1 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8 8 8 8 8

    2 0 0 0 0 2 2 2 2 2 8

    3

    4              A2=2,B2=4

    5
表を埋める
•   dp(t,i+1)=下の2つのmax
    •   夜店 i+1 で遊ぶ→時刻(t - Bi+1)で夜店 i まで遊んだ時の楽しさ + Ai+1
    •   夜店i+1で遊ばない→時刻 t で夜店 i まで遊んだ時の楽しさ
•   数式で書くとdp(t , i+1)=max{dp(t - Bi+1, i) + Ai+1 , dp(t,i)}

    dp 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

    1 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8 8 8 8 8

    2 0 0 0 0 2 2 2 2 2 8 8 8 8 10 10 10 10 10 10 10 10

    3 0 0 0 0 2 2 2 2 2 8 8 8 8 10 10 10 10 10 10 10 10

    4 0 0 0 A2=2,B6=4 8 8 8 8 8 14 14 141 16 16 16 16 16
            6 6 2 6                     14

    5 0 0 0 6 6 6 6 8 8 8 8 11 14 14 14 14 16 16 16 16 19
計算量




•   表のマス目はN×T=3000×3000=9000000(10^7くらい)個
•   できそう!
•   O(NT)
•   参考:10点の解法では2^3000=100......................00(10^900ぐらい) の組み合わせを考えていた
計算量
                  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

                1 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8 8 8 8 8

                2 0 0 0 0 2 2 2 2 2 8 8 8 8 10 10 10 10 10 10 10 10

                3 0 0 0 0 2 2 2 2 2 8 8 8 8 10 10 10 10 10 10 10 10

                4 0 0 0 6 6 6 6 8 8 8 8 8 14 14 14114 16 16 16 16 16

                5 0 0 0 6 6 6 6 8 8 8 8 11 14 14 14 14 16 16 16 16 19




•   表のマス目はN×T=3000×3000=9000000(10^7くらい)個
•   できそう!
•   O(NT)
•   参考:10点の解法では2^3000=100......................00(10^900ぐらい) の組み合わせを考えていた
ここまでで30点
じゃあ花火が途中であったらどうするよ

                   8

           2

                       7

       6

               5


• 花火までに行く夜店                と 花火の後に行く夜店 の2つに
    とりあえず分けてみる
•   分け方はN+1=約3000通りしかないから大丈夫じゃない?
•   →ナップサック問題を2つ解けばいい!
じゃあ花火が途中であったらどうするよ

            8                6

        2                        5

                7




• 花火までに行く夜店         と 花火の後に行く夜店 の2つに
    とりあえず分けてみる
•   分け方はN+1=約3000通りしかないから大丈夫じゃない?
•   →ナップサック問題を2つ解けばいい!
できそうだけど…?


•   表のマス目がN×T=9000000個
•   場合分けが3000通り
•   掛け算すると27000000000(10^10以上)
•   1秒に収めるにはちょっと厳しい.
•   O(N^2T)
表を眺めてみる
         dp 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
         1 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8
         2 0 0 0 0 2 2 2 2 2 8 8 8 8 10 10
         3 0 0 0 0 2 2 2 2 2 8 8 8 8 10 10
         4 0 0 0 6 6 6 6 8 8 8 8 8 14 14 141
         5 0 0 0 6 6 6 6 8 8 8 8 11 14 14 14

•   花火があるまでに,夜店1まで遊ぶ,夜店2まで遊ぶ,...,
    夜店Nまで遊ぶ,は全部同じ表で求まる!
•   花火の後の部分も同様.
•   ただしdp(t,i)=時刻tから終了時刻までに夜店i~Nを遊ぶ,として考えなければならない
完成!
dp1   0 1 2 3 4 5 6 7 8 9 10 11 12 13   14           14   15 16 17 18 19 20   dp2
                                             0
1 0 0 0 0 0 0 0 0 0 8 8 8 8 8           8            6    6 6 6 0 0 0 1

2 0 0 0 0 2 2 2 2 2 8 8 8 8 10          10           6    6 6 6 0 0 0 2

3 0 0 0 0 2 2 2 2 2 8 8 8 8 10          10           6    6 6 6 0 0 0 3

4 0 0 0 6 6 6 6 8 8 8 8 8 14 14         14           6    6 6 6 0 0 0 4

5 0 0 0 6 6 6 6 8 8 8 8 11 14 14        14           0    0 0 0 0 0 0 5
                                                 0
• dp1(S,i)+dp2(S,i+1)     の最大値がMの最大値!
      (この場合は16)
• N×T個のマス目を埋める                     + N通りの組み合わせを見る
      時間的にも大丈夫そう O(NT)
ちなみに
解法はひとつ!じゃない!!
•   表を左から右に,上から下に見ていく
•   tt=時刻 t 以降に夜店i+1で遊びはじめて遊び終わる時刻とする
  tt=if(t<S<t+Bi+1) then (S+Bi+1) else (t+Bi+1)
• dp(t,i)+Ai+1をdp(tt,i+1)と比べて大きければ書き込む

•   dp(t,i)をdp(t+1,i)と比べて大きければ書き込む
•   dp(t,i)をdp(t,i+1)と比べて大きければ書き込む

    dp 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
    1   0   0   0   0   0   0   0   0   0   8   8   8 8 8 8 8 8 8 8 8 8
    2   0   0   0   0   2   2   2   2   2   8   8   8 8 10 10 10 10 10 10 10 10
    3   0   0   0   0   2   2   2   2   2   8   8   8 8 10 10 10 10 10 10 10 10
    4   0   0   0   6   6   6   6   8   8   8   8   8 14 14 141 16 16 16 16 16
                                                                14
    5   0   0   0   6   6   6   6   8   8   8   8   11 14 14 14 14 16 16 16 16 16
ちなみ2
DPについてもっと知りたい!
•   プログラミングコンテストでの動的計画法
    http://www.slideshare.net/iwiwi/ss-3578511



•   最強最速アルゴリズマー養成講座
    http://www.itmedia.co.jp/enterprise/articles/1003/06/news002.html
    http://www.itmedia.co.jp/enterprise/articles/1005/15/news002.html




•   どちらもタイトルでgoogle検索すればすぐ出ます
ちなみ3
結果




0   10   20   30   40   50   60   70   80   90   100
ありがとうございました

More Related Content

What's hot (12)

AtCoder Regular Contest 021 解説
AtCoder Regular Contest 021 解説AtCoder Regular Contest 021 解説
AtCoder Regular Contest 021 解説
 
AtCoder Beginner Contest 035 解説
AtCoder Beginner Contest 035 解説AtCoder Beginner Contest 035 解説
AtCoder Beginner Contest 035 解説
 
AtCoder Beginner Contest 025 解説
AtCoder Beginner Contest 025 解説AtCoder Beginner Contest 025 解説
AtCoder Beginner Contest 025 解説
 
Haskell で nクィーン問題を解く
Haskell で nクィーン問題を解くHaskell で nクィーン問題を解く
Haskell で nクィーン問題を解く
 
動的計画法
動的計画法動的計画法
動的計画法
 
AtCoder Regular Contest 030 解説
AtCoder Regular Contest 030 解説AtCoder Regular Contest 030 解説
AtCoder Regular Contest 030 解説
 
AtCoder Beginner Contest 011 解説
AtCoder Beginner Contest 011 解説AtCoder Beginner Contest 011 解説
AtCoder Beginner Contest 011 解説
 
Coursera "Neural Networks"
Coursera "Neural Networks"Coursera "Neural Networks"
Coursera "Neural Networks"
 
AtCoder Beginner Contest 005 解説
AtCoder Beginner Contest 005 解説AtCoder Beginner Contest 005 解説
AtCoder Beginner Contest 005 解説
 
AtCoder Beginner Contest 008 解説
AtCoder Beginner Contest 008 解説AtCoder Beginner Contest 008 解説
AtCoder Beginner Contest 008 解説
 
Za atsu-20170328
Za atsu-20170328Za atsu-20170328
Za atsu-20170328
 
AtCoder Beginner Contest 018 解説
AtCoder Beginner Contest 018 解説AtCoder Beginner Contest 018 解説
AtCoder Beginner Contest 018 解説
 

Similar to JOI本選 夜店(NightMarket)解説

AtCoder Regular Contest 027 解説
AtCoder Regular Contest 027 解説AtCoder Regular Contest 027 解説
AtCoder Regular Contest 027 解説AtCoder Inc.
 
日本情報オリンピック旗(JOI Flag) 解説
日本情報オリンピック旗(JOI Flag) 解説日本情報オリンピック旗(JOI Flag) 解説
日本情報オリンピック旗(JOI Flag) 解説Kensuke Imanishi
 
K2PC Div1 E 暗号化
K2PC Div1 E 暗号化K2PC Div1 E 暗号化
K2PC Div1 E 暗号化Kazuma Mikami
 
Mastermind
MastermindMastermind
Mastermindtomerun
 
30分で博士号がとれる画像処理講座
30分で博士号がとれる画像処理講座30分で博士号がとれる画像処理講座
30分で博士号がとれる画像処理講座Sakiyama Kei
 
CODE FESTIVAL 2015 沖縄ツアー 解説
CODE FESTIVAL 2015 沖縄ツアー 解説CODE FESTIVAL 2015 沖縄ツアー 解説
CODE FESTIVAL 2015 沖縄ツアー 解説AtCoder Inc.
 
S1_第2回DSEカンファレンス資料_okura
S1_第2回DSEカンファレンス資料_okuraS1_第2回DSEカンファレンス資料_okura
S1_第2回DSEカンファレンス資料_okurayoroz okura
 
金大アルゴリズム勉強会#004資料
金大アルゴリズム勉強会#004資料金大アルゴリズム勉強会#004資料
金大アルゴリズム勉強会#004資料Takumi Murano
 
Atcoder Regular Contest 014 解説
Atcoder Regular Contest 014 解説Atcoder Regular Contest 014 解説
Atcoder Regular Contest 014 解説光喜 濱屋
 
AtCoder Beginner Contest 009 解説
AtCoder Beginner Contest 009 解説AtCoder Beginner Contest 009 解説
AtCoder Beginner Contest 009 解説AtCoder Inc.
 
ZDD入門-お姉さんを救う方法
ZDD入門-お姉さんを救う方法ZDD入門-お姉さんを救う方法
ZDD入門-お姉さんを救う方法nishio
 
部内勉強会 数え上げの基礎
部内勉強会 数え上げの基礎部内勉強会 数え上げの基礎
部内勉強会 数え上げの基礎Kazuma Mikami
 
CODE FESTIVAL 2014 本選 解説
CODE FESTIVAL 2014 本選 解説CODE FESTIVAL 2014 本選 解説
CODE FESTIVAL 2014 本選 解説AtCoder Inc.
 
算数で体感する高度数学
算数で体感する高度数学算数で体感する高度数学
算数で体感する高度数学Arithmer Inc.
 
Joi模擬予選2013 6番解説
Joi模擬予選2013 6番解説Joi模擬予選2013 6番解説
Joi模擬予選2013 6番解説DEGwer
 

Similar to JOI本選 夜店(NightMarket)解説 (19)

AtCoder Regular Contest 027 解説
AtCoder Regular Contest 027 解説AtCoder Regular Contest 027 解説
AtCoder Regular Contest 027 解説
 
立命合宿2016Day3:G問題
立命合宿2016Day3:G問題立命合宿2016Day3:G問題
立命合宿2016Day3:G問題
 
日本情報オリンピック旗(JOI Flag) 解説
日本情報オリンピック旗(JOI Flag) 解説日本情報オリンピック旗(JOI Flag) 解説
日本情報オリンピック旗(JOI Flag) 解説
 
K2PC Div1 E 暗号化
K2PC Div1 E 暗号化K2PC Div1 E 暗号化
K2PC Div1 E 暗号化
 
Mastermind
MastermindMastermind
Mastermind
 
30分で博士号がとれる画像処理講座
30分で博士号がとれる画像処理講座30分で博士号がとれる画像処理講座
30分で博士号がとれる画像処理講座
 
CODE FESTIVAL 2015 沖縄ツアー 解説
CODE FESTIVAL 2015 沖縄ツアー 解説CODE FESTIVAL 2015 沖縄ツアー 解説
CODE FESTIVAL 2015 沖縄ツアー 解説
 
Aizu-2017: B
Aizu-2017: BAizu-2017: B
Aizu-2017: B
 
S1_第2回DSEカンファレンス資料_okura
S1_第2回DSEカンファレンス資料_okuraS1_第2回DSEカンファレンス資料_okura
S1_第2回DSEカンファレンス資料_okura
 
写像 12 相
写像 12 相写像 12 相
写像 12 相
 
金大アルゴリズム勉強会#004資料
金大アルゴリズム勉強会#004資料金大アルゴリズム勉強会#004資料
金大アルゴリズム勉強会#004資料
 
Atcoder Regular Contest 014 解説
Atcoder Regular Contest 014 解説Atcoder Regular Contest 014 解説
Atcoder Regular Contest 014 解説
 
Abc009
Abc009Abc009
Abc009
 
AtCoder Beginner Contest 009 解説
AtCoder Beginner Contest 009 解説AtCoder Beginner Contest 009 解説
AtCoder Beginner Contest 009 解説
 
ZDD入門-お姉さんを救う方法
ZDD入門-お姉さんを救う方法ZDD入門-お姉さんを救う方法
ZDD入門-お姉さんを救う方法
 
部内勉強会 数え上げの基礎
部内勉強会 数え上げの基礎部内勉強会 数え上げの基礎
部内勉強会 数え上げの基礎
 
CODE FESTIVAL 2014 本選 解説
CODE FESTIVAL 2014 本選 解説CODE FESTIVAL 2014 本選 解説
CODE FESTIVAL 2014 本選 解説
 
算数で体感する高度数学
算数で体感する高度数学算数で体感する高度数学
算数で体感する高度数学
 
Joi模擬予選2013 6番解説
Joi模擬予選2013 6番解説Joi模擬予選2013 6番解説
Joi模擬予選2013 6番解説
 

More from Hiroshi Yamashita

充足可能性問題のいろいろ
充足可能性問題のいろいろ充足可能性問題のいろいろ
充足可能性問題のいろいろHiroshi Yamashita
 
2015 JOI春合宿 Day3 AAQQZ 解説
2015 JOI春合宿 Day3 AAQQZ 解説2015 JOI春合宿 Day3 AAQQZ 解説
2015 JOI春合宿 Day3 AAQQZ 解説Hiroshi Yamashita
 
2014 JOI春合宿 行列の基礎とその応用
2014 JOI春合宿 行列の基礎とその応用2014 JOI春合宿 行列の基礎とその応用
2014 JOI春合宿 行列の基礎とその応用Hiroshi Yamashita
 
2013 JOI春合宿 Day4 漢字しりとり (Kanji Shiritori) 解説
2013 JOI春合宿 Day4 漢字しりとり (Kanji Shiritori) 解説2013 JOI春合宿 Day4 漢字しりとり (Kanji Shiritori) 解説
2013 JOI春合宿 Day4 漢字しりとり (Kanji Shiritori) 解説Hiroshi Yamashita
 
2013 JOI春合宿 講義6 機械学習入門
2013 JOI春合宿 講義6 機械学習入門2013 JOI春合宿 講義6 機械学習入門
2013 JOI春合宿 講義6 機械学習入門Hiroshi Yamashita
 
2013 JOI春合宿 Day2 Spy(スパイ) 解説
2013 JOI春合宿 Day2 Spy(スパイ) 解説2013 JOI春合宿 Day2 Spy(スパイ) 解説
2013 JOI春合宿 Day2 Spy(スパイ) 解説Hiroshi Yamashita
 
JOI春合宿Day4中華料理(Chinese)解説
JOI春合宿Day4中華料理(Chinese)解説JOI春合宿Day4中華料理(Chinese)解説
JOI春合宿Day4中華料理(Chinese)解説Hiroshi Yamashita
 

More from Hiroshi Yamashita (7)

充足可能性問題のいろいろ
充足可能性問題のいろいろ充足可能性問題のいろいろ
充足可能性問題のいろいろ
 
2015 JOI春合宿 Day3 AAQQZ 解説
2015 JOI春合宿 Day3 AAQQZ 解説2015 JOI春合宿 Day3 AAQQZ 解説
2015 JOI春合宿 Day3 AAQQZ 解説
 
2014 JOI春合宿 行列の基礎とその応用
2014 JOI春合宿 行列の基礎とその応用2014 JOI春合宿 行列の基礎とその応用
2014 JOI春合宿 行列の基礎とその応用
 
2013 JOI春合宿 Day4 漢字しりとり (Kanji Shiritori) 解説
2013 JOI春合宿 Day4 漢字しりとり (Kanji Shiritori) 解説2013 JOI春合宿 Day4 漢字しりとり (Kanji Shiritori) 解説
2013 JOI春合宿 Day4 漢字しりとり (Kanji Shiritori) 解説
 
2013 JOI春合宿 講義6 機械学習入門
2013 JOI春合宿 講義6 機械学習入門2013 JOI春合宿 講義6 機械学習入門
2013 JOI春合宿 講義6 機械学習入門
 
2013 JOI春合宿 Day2 Spy(スパイ) 解説
2013 JOI春合宿 Day2 Spy(スパイ) 解説2013 JOI春合宿 Day2 Spy(スパイ) 解説
2013 JOI春合宿 Day2 Spy(スパイ) 解説
 
JOI春合宿Day4中華料理(Chinese)解説
JOI春合宿Day4中華料理(Chinese)解説JOI春合宿Day4中華料理(Chinese)解説
JOI春合宿Day4中華料理(Chinese)解説
 

JOI本選 夜店(NightMarket)解説

  • 2. 問題のおさらい • N個の夜店のなかから順番通りにいくつか選んで遊ぶ • 夜店で遊べる時間はTだけ • 遊んでいる時間が時刻Sに被ってはいけない • 楽しさの合計を最大にする 花火 夜店1 8 楽しさの合計M=8+2+6=16 夜店2 2 夜店3 7 夜店4 6 夜店5 5
  • 3. 問題のおさらい • N個の夜店のなかから順番通りにいくつか選んで遊ぶ • 夜店で遊べる時間はTだけ • 遊んでいる時間が時刻Sに被ってはいけない • 楽しさの合計を最大にする 花火 8 2 6 夜店1 楽しさの合計M=8+2+6=16 夜店2 夜店3 7 夜店4 夜店5 5
  • 4. まずは力技で • とりあえず全通り選んでみて入れてみる 8 8 2 2 7 7 6 6 5 5 • N=20なら2^20=約1000000(10^6)通り試せばできる
  • 5. まずは力技で • とりあえず全通り選んでみて入れてみる 8 2 7 8 失敗! 2 7 6 6 5 5 • N=20なら2^20=約1000000(10^6)通り試せばできる
  • 6. まずは力技で • とりあえず全通り選んでみて入れてみる 8 2 7 6 7 M=7+6=13 8 失敗! 2 6 5 5 • N=20なら2^20=約1000000(10^6)通り試せばできる
  • 7. まずは力技で • とりあえず全通り選んでみて入れてみる 8 2 7 6 7 M=7+6=13 8 失敗! 2 6 5 5 N=20なら2^20=約1000000(10^6)通り試せばできる • • N=3000なら2^3000=100......................00(10^900ぐらい)も! • 10%以上の得点は無理そう… • O(2^N)
  • 9. もしも花火が到着の瞬間に打ち上がったら 花火 夜店1 8 夜店2 2 夜店3 7 夜店4 6 夜店5 5 • 花火大会がなくなったのと同じ状況 • ちょっと簡単になった.でもどうしよう?
  • 10. もしも花火が到着の瞬間に打ち上がったら 花火 夜店1 8 夜店2 2 夜店3 7 夜店4 6 夜店5 5 • 花火大会がなくなったのと同じ状況 • ちょっと簡単になった.でもどうしよう? →動的計画法(DP)が使える
  • 11. 動的計画法(DP)って何さ • おなじみの人にはおなじみDynamic Programming • ある最適化問題を複数の部分問題に分割して解く際に、そこまでに求められている以上 の最適解が求められないような部分問題を切り捨てながら解いていく手法である。 (Wikipediaより) • 100番目のフィボナッチ数(1,1,2,3,5,8,...)の計算で例える • k番目までのフィボナッチ数が分かっていた(部分問 題)ら,k-1番目の物とk番目の物を足せばk+1番目の ものが分かる • これを繰り返すと100番目のフィボナッチ数がわかる • 途中まで計算した結果を用いて次の計算をする
  • 12. ナップサック問題 • 動的計画法(DP)の典型的な応用例 • ナップサックに,いろんな体積と値段の荷物を入れる • 荷物の体積の合計をナップサックの体積以下にしなが ら,値段の合計を出来るだけ大きくする ナップサック問題 今回の問題(S=0の場合) 8 8 5 2 7 2 6 7 6 5 一緒!
  • 13. やってみよう • 時刻 t までに,夜店 i までを遊ぶときの楽しさの最高をもと める(その答えをdp(t,i)と置いておきます) • dp(t,i+1)を求めたい • 夜店 i+1 で遊ぶ →時刻(t - Bi+1)で夜店 i まで遊んだ時の楽しさ + Ai+1 • 夜店i+1で遊ばない →時刻 t で夜店 i まで遊んだ時の楽しさ • この二つの大きい方を取る!
  • 14. 表を埋める • dp(t,i+1)=下の2つのmax • 夜店 i+1 で遊ぶ→時刻(t - Bi+1)で夜店 i まで遊んだ時の楽しさ + Ai+1 • 夜店i+1で遊ばない→時刻 t で夜店 i まで遊んだ時の楽しさ • 数式で書くとdp(t , i+1)=max{dp(t - Bi+1, i) + Ai+1 , dp(t,i)} dp 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8 8 8 8 8 2 0 0 0 0 3 4 A2=2,B2=4 5
  • 15. 表を埋める • dp(t,i+1)=下の2つのmax • 夜店 i+1 で遊ぶ→時刻(t - Bi+1)で夜店 i まで遊んだ時の楽しさ + Ai+1 • 夜店i+1で遊ばない→時刻 t で夜店 i まで遊んだ時の楽しさ • 数式で書くとdp(t , i+1)=max{dp(t - Bi+1, i) + Ai+1 , dp(t,i)} dp 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8 8 8 8 8 2 0 0 0 0 2 3 4 A2=2,B2=4 5
  • 16. 表を埋める • dp(t,i+1)=下の2つのmax • 夜店 i+1 で遊ぶ→時刻(t - Bi+1)で夜店 i まで遊んだ時の楽しさ + Ai+1 • 夜店i+1で遊ばない→時刻 t で夜店 i まで遊んだ時の楽しさ • 数式で書くとdp(t , i+1)=max{dp(t - Bi+1, i) + Ai+1 , dp(t,i)} dp 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8 8 8 8 8 2 0 0 0 0 2 2 2 2 2 3 4 A2=2,B2=4 5
  • 17. 表を埋める • dp(t,i+1)=下の2つのmax • 夜店 i+1 で遊ぶ→時刻(t - Bi+1)で夜店 i まで遊んだ時の楽しさ + Ai+1 • 夜店i+1で遊ばない→時刻 t で夜店 i まで遊んだ時の楽しさ • 数式で書くとdp(t , i+1)=max{dp(t - Bi+1, i) + Ai+1 , dp(t,i)} dp 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8 8 8 8 8 2 0 0 0 0 2 2 2 2 2 8 3 4 A2=2,B2=4 5
  • 18. 表を埋める • dp(t,i+1)=下の2つのmax • 夜店 i+1 で遊ぶ→時刻(t - Bi+1)で夜店 i まで遊んだ時の楽しさ + Ai+1 • 夜店i+1で遊ばない→時刻 t で夜店 i まで遊んだ時の楽しさ • 数式で書くとdp(t , i+1)=max{dp(t - Bi+1, i) + Ai+1 , dp(t,i)} dp 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8 8 8 8 8 2 0 0 0 0 2 2 2 2 2 8 8 8 8 10 10 10 10 10 10 10 10 3 0 0 0 0 2 2 2 2 2 8 8 8 8 10 10 10 10 10 10 10 10 4 0 0 0 A2=2,B6=4 8 8 8 8 8 14 14 141 16 16 16 16 16 6 6 2 6 14 5 0 0 0 6 6 6 6 8 8 8 8 11 14 14 14 14 16 16 16 16 19
  • 19. 計算量 • 表のマス目はN×T=3000×3000=9000000(10^7くらい)個 • できそう! • O(NT) • 参考:10点の解法では2^3000=100......................00(10^900ぐらい) の組み合わせを考えていた
  • 20. 計算量 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8 8 8 8 8 2 0 0 0 0 2 2 2 2 2 8 8 8 8 10 10 10 10 10 10 10 10 3 0 0 0 0 2 2 2 2 2 8 8 8 8 10 10 10 10 10 10 10 10 4 0 0 0 6 6 6 6 8 8 8 8 8 14 14 14114 16 16 16 16 16 5 0 0 0 6 6 6 6 8 8 8 8 11 14 14 14 14 16 16 16 16 19 • 表のマス目はN×T=3000×3000=9000000(10^7くらい)個 • できそう! • O(NT) • 参考:10点の解法では2^3000=100......................00(10^900ぐらい) の組み合わせを考えていた
  • 22. じゃあ花火が途中であったらどうするよ 8 2 7 6 5 • 花火までに行く夜店 と 花火の後に行く夜店 の2つに とりあえず分けてみる • 分け方はN+1=約3000通りしかないから大丈夫じゃない? • →ナップサック問題を2つ解けばいい!
  • 23. じゃあ花火が途中であったらどうするよ 8 6 2 5 7 • 花火までに行く夜店 と 花火の後に行く夜店 の2つに とりあえず分けてみる • 分け方はN+1=約3000通りしかないから大丈夫じゃない? • →ナップサック問題を2つ解けばいい!
  • 24. できそうだけど…? • 表のマス目がN×T=9000000個 • 場合分けが3000通り • 掛け算すると27000000000(10^10以上) • 1秒に収めるにはちょっと厳しい. • O(N^2T)
  • 25. 表を眺めてみる dp 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 2 0 0 0 0 2 2 2 2 2 8 8 8 8 10 10 3 0 0 0 0 2 2 2 2 2 8 8 8 8 10 10 4 0 0 0 6 6 6 6 8 8 8 8 8 14 14 141 5 0 0 0 6 6 6 6 8 8 8 8 11 14 14 14 • 花火があるまでに,夜店1まで遊ぶ,夜店2まで遊ぶ,..., 夜店Nまで遊ぶ,は全部同じ表で求まる! • 花火の後の部分も同様. • ただしdp(t,i)=時刻tから終了時刻までに夜店i~Nを遊ぶ,として考えなければならない
  • 26. 完成! dp1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 14 15 16 17 18 19 20 dp2 0 1 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 6 6 6 6 0 0 0 1 2 0 0 0 0 2 2 2 2 2 8 8 8 8 10 10 6 6 6 6 0 0 0 2 3 0 0 0 0 2 2 2 2 2 8 8 8 8 10 10 6 6 6 6 0 0 0 3 4 0 0 0 6 6 6 6 8 8 8 8 8 14 14 14 6 6 6 6 0 0 0 4 5 0 0 0 6 6 6 6 8 8 8 8 11 14 14 14 0 0 0 0 0 0 0 5 0 • dp1(S,i)+dp2(S,i+1) の最大値がMの最大値! (この場合は16) • N×T個のマス目を埋める + N通りの組み合わせを見る 時間的にも大丈夫そう O(NT)
  • 28. 解法はひとつ!じゃない!! • 表を左から右に,上から下に見ていく • tt=時刻 t 以降に夜店i+1で遊びはじめて遊び終わる時刻とする tt=if(t<S<t+Bi+1) then (S+Bi+1) else (t+Bi+1) • dp(t,i)+Ai+1をdp(tt,i+1)と比べて大きければ書き込む • dp(t,i)をdp(t+1,i)と比べて大きければ書き込む • dp(t,i)をdp(t,i+1)と比べて大きければ書き込む dp 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8 8 8 8 8 2 0 0 0 0 2 2 2 2 2 8 8 8 8 10 10 10 10 10 10 10 10 3 0 0 0 0 2 2 2 2 2 8 8 8 8 10 10 10 10 10 10 10 10 4 0 0 0 6 6 6 6 8 8 8 8 8 14 14 141 16 16 16 16 16 14 5 0 0 0 6 6 6 6 8 8 8 8 11 14 14 14 14 16 16 16 16 16
  • 30. DPについてもっと知りたい! • プログラミングコンテストでの動的計画法 http://www.slideshare.net/iwiwi/ss-3578511 • 最強最速アルゴリズマー養成講座 http://www.itmedia.co.jp/enterprise/articles/1003/06/news002.html http://www.itmedia.co.jp/enterprise/articles/1005/15/news002.html • どちらもタイトルでgoogle検索すればすぐ出ます
  • 32. 結果 0 10 20 30 40 50 60 70 80 90 100

Editor's Notes

  1. \n
  2. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n\n
  3. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n\n
  4. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n\n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  19. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  20. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  21. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  22. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  23. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  24. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  25. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  26. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  27. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  28. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  29. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  30. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  31. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  32. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  45. \n
  46. 5 20 14\n8 9\n2 4\n7 13\n6 3\n5 8\n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n