∼シチュエーション別∼Perlでちょいモテアルゴリズム  2012/01/27 Livedoor DeNA 合同勉強会     萬野有生 @DeNA id: mandy_44
Case1:
Case1:「運命の人なら誕生日くらい当て られるよね!?9回で当てられ ないと・・・(*́ω`*)」
Case1:「運命の人なら誕生日くらい当て られるよね!?9回で当てられ ないと・・・(*́ω`*)」電波ですか?a(°Д°ill
彼女の誕生日を9回以内に当てよ!ただしはずれると彼女は誕生日がそれより後か前か教えてくれる。
1/1   1/2   ・・・   6/30   7/1    7/2    ・・・   12/30 12/317/1   7/2   ・・・   9/30   10/1   10/2   ・・・   12/30 12/317/1   7/2 ...
#!/usr/bin/perluse strict;use warnings;                                    中間値を取ってきてそのmy $MAX_LOOP = 9;                   ...
#!/usr/bin/perluse strict;use warnings;                                     中間値を取ってきてそのmy $MAX_LOOP = 9;                  ...
Case2:
Case2:「私、1日でなるべくいっぱい映画 を見たいの☆(ゝω・)vキャピ」
Case2:「私、1日でなるべくいっぱい映画 を見たいの☆(ゝω・)vキャピ」DVD借りようよ(;・ ・)
n本の映画が上映されている。各映画は時刻siに始まりeiに終了する。できるだけ多くの映画を見たいとき何本見ることができるか。ただし途中入退場は出来ない。
2       41       3       5                    時間
2       4   1       3       5                       時間1.一番開始時間の早いものから見る2.一番時間の短いものから見る3.一番終了時間の早いものから見る
2       4       1       3       5                           時間   1.一番開始時間の早いものから見る   2.一番時間の短いものから見る   3.一番終了時間の早いものから見る今、...
2       4       1       3       5                           時間   1.一番開始時間の早いものから見る   2.一番時間の短いものから見る   3.一番終了時間の早いものから見る今、...
#!/usr/bin/perluse strict;use warnings;                                                       終了時間でソート# 映画のリスト            ...
#!/usr/bin/perluse strict;use warnings;                                                       終了時間でソート# 映画のリスト            ...
Case3:
Case3:「何でも食べていいんだよねっ? 何食べたら一番お腹いっぱいに なるかなー♪(・ ・)」
Case3:「何でも食べていいんだよねっ? 何食べたら一番お腹いっぱいに なるかなー♪(・ ・)」5万円まででお願いします    (ヽ ω`)
n種類の料理のリストがある。各料理はpiの値段でviの量がある。X万円以内で一番量が多くなる料理の組み合わせを見つけよ。※ただし料理は1種類につき1回しか頼めない
i番目の料理を食べるか食べないかで総当たり                 → 計算量はO(2^n)
i番目の料理を食べるか食べないかで総当たり                 → 計算量はO(2^n)    i番目の料理を食べる、食べない、に分解      食べた時           食べない時X-pi円でi番目以外の料    X円でi番目...
i番目の料理を食べるか食べないかで総当たり                 → 計算量はO(2^n)    i番目の料理を食べる、食べない、に分解      食べた時              食べない時X-pi円でi番目以外の料       ...
i番目の料理を食べるか食べないかで総当たり                 → 計算量はO(2^n)    i番目の料理を食べる、食べない、に分解      食べた時              食べない時X-pi円でi番目以外の料       ...
i番目(i=0∼n-1)までの料理をj万円以内で食べた時の量の最大値をdp[i+1][j]とおくi→i+1とするときの遷移を考えると、以下の漸化式が導ける
i番目(i=0∼n-1)までの料理をj万円以内で食    べた時の量の最大値をdp[i+1][j]とおく    i→i+1とするときの遷移を考えると、以下の    漸化式が導ける             dp[i][j] (j < v[i])d...
#!/usr/bin/perluse strict;use warnings;use List::Util qw(max);my   $n   =   4;                        計算量はたかだかO(nX)my   @p...
#!/usr/bin/perluse strict;use warnings;use List::Util qw(max);my   $n   =   4;                        計算量はたかだかO(nX)my   @p...
Case4:
Case4:「今度の旅行楽しみだねー♪でも 私最短距離で移動しないと怒っちゃうぞっ(o≧▽゚)o」
Case4:「今度の旅行楽しみだねー♪でも 私最短距離で移動しないと怒っ ちゃうぞっ(o≧▽゚)o」新幹線で(ry (;́ `)
n個の地点がある。各地点間の道路の距離が与えられた時、地点iから地点jまでの最短経路を求めよ。
3        2                 9    8                 10    41                 11            12             この問題は左図のようなグラフで表され...
3        2                 9    8                    10       41                 11            12                  この問題は左図...
3        2                 9                ワーシャルフロイド    8                    10       41                 11            12...
#!/usr/bin/perl                               $p[$i][$j]は、use strict;use warnings;                               直通の道あり → ...
#!/usr/bin/perl                               $p[$i][$j]は、use strict;use warnings;                               直通の道あり → ...
Thank you very much for your attention.
Upcoming SlideShare
Loading in...5
×

20120127 nhn

1,096

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,096
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • &amp;#x9069;&amp;#x7528;&amp;#x4F8B;&amp;#x306F;&amp;#x30A8;&amp;#x30EC;&amp;#x30D9;&amp;#x30FC;&amp;#x30BF;&amp;#x30FC;&amp;#x3068;&amp;#x304B;\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • &amp;#x5B9F;&amp;#x7528;&amp;#x4F8B;&amp;#x3068;&amp;#x3057;&amp;#x3066;&amp;#x30AB;&amp;#x30FC;&amp;#x30C9;&amp;#x30B2;&amp;#x30FC;&amp;#x30E0;&amp;#x306E;&amp;#x6700;&amp;#x5927;&amp;#x30B3;&amp;#x30B9;&amp;#x30C8;&amp;#x306B;&amp;#x5BFE;&amp;#x3059;&amp;#x308B;&amp;#x6226;&amp;#x529B;&amp;#x306E;&amp;#x6700;&amp;#x5927;&amp;#x5316;&amp;#x3001;&amp;#x306A;&amp;#x3069;\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • &amp;#x30C0;&amp;#x30A4;&amp;#x30AF;&amp;#x30B9;&amp;#x30C8;&amp;#x30E9;&amp;#x6CD5;&amp;#x3068;&amp;#x3044;&amp;#x3046;&amp;#x3082;&amp;#x306E;&amp;#x3082;&amp;#x3042;&amp;#x308B;&amp;#x304C;&amp;#x91CD;&amp;#x307F;&amp;#x304C;&amp;#x8CA0;&amp;#x306E;&amp;#x6642;&amp;#x306B;&amp;#x304A;&amp;#x304B;&amp;#x3057;&amp;#x304F;&amp;#x306A;&amp;#x308B;\n&amp;#x3053;&amp;#x308C;&amp;#x306F;&amp;#x7121;&amp;#x5411;&amp;#x30B0;&amp;#x30E9;&amp;#x30D5;&amp;#x3060;&amp;#x3063;&amp;#x305F;&amp;#x304C;&amp;#x6709;&amp;#x5411;&amp;#x30B0;&amp;#x30E9;&amp;#x30D5;&amp;#x3067;&amp;#x3082;WF&amp;#x306F;&amp;#x9069;&amp;#x7528;&amp;#x53EF;&amp;#x80FD;\n&amp;#x5B9F;&amp;#x7528;&amp;#x4F8B;&amp;#x306F;&amp;#x4E57;&amp;#x308A;&amp;#x63DB;&amp;#x3048;&amp;#x6848;&amp;#x5185;&amp;#x3001;&amp;#x306A;&amp;#x3069;\n
  • \n
  • 20120127 nhn

    1. 1. ∼シチュエーション別∼Perlでちょいモテアルゴリズム 2012/01/27 Livedoor DeNA 合同勉強会 萬野有生 @DeNA id: mandy_44
    2. 2. Case1:
    3. 3. Case1:「運命の人なら誕生日くらい当て られるよね!?9回で当てられ ないと・・・(*́ω`*)」
    4. 4. Case1:「運命の人なら誕生日くらい当て られるよね!?9回で当てられ ないと・・・(*́ω`*)」電波ですか?a(°Д°ill
    5. 5. 彼女の誕生日を9回以内に当てよ!ただしはずれると彼女は誕生日がそれより後か前か教えてくれる。
    6. 6. 1/1 1/2 ・・・ 6/30 7/1 7/2 ・・・ 12/30 12/317/1 7/2 ・・・ 9/30 10/1 10/2 ・・・ 12/30 12/317/1 7/2 ・・・ 8/14 8/15 8/16 ・・・ 9/29 9/30
    7. 7. #!/usr/bin/perluse strict;use warnings; 中間値を取ってきてそのmy $MAX_LOOP = 9; 前後どちらにあるか判定my $doy = 250; # 9/7my ($min $max) = (0, 365);my $ans;for (1..$MAX_LOOP) { 計算量はO(log2n)    my $mid = int(($min+$max)/2);    if ($mid == $doy) {        $ans = $mid; 並列N分探索は強力        last;    }    elsif($mid > $doy) {        $max = $mid;    }    else {        $min = $mid;    }}print "ans: ", $ans, "n";
    8. 8. #!/usr/bin/perluse strict;use warnings; 中間値を取ってきてそのmy $MAX_LOOP = 9; 前後どちらにあるか判定my $doy = 250; # 9/7my ($min $max) = (0, 365);my $ans;for (1..$MAX_LOOP) { 計算量はO(log2n)    my $mid = int(($min+$max)/2);    if ($mid == $doy) {        $ans = $mid; 並列N分探索は強力        last;    }    elsif($mid > $doy) {        $max = $mid;    }    else {        $min = $mid; じわりじわりと攻めていく    }}print "ans: ", $ans, "n";
    9. 9. Case2:
    10. 10. Case2:「私、1日でなるべくいっぱい映画 を見たいの☆(ゝω・)vキャピ」
    11. 11. Case2:「私、1日でなるべくいっぱい映画 を見たいの☆(ゝω・)vキャピ」DVD借りようよ(;・ ・)
    12. 12. n本の映画が上映されている。各映画は時刻siに始まりeiに終了する。できるだけ多くの映画を見たいとき何本見ることができるか。ただし途中入退場は出来ない。
    13. 13. 2 41 3 5 時間
    14. 14. 2 4 1 3 5 時間1.一番開始時間の早いものから見る2.一番時間の短いものから見る3.一番終了時間の早いものから見る
    15. 15. 2 4 1 3 5 時間 1.一番開始時間の早いものから見る 2.一番時間の短いものから見る 3.一番終了時間の早いものから見る今、その時点で一番○○なものを選んでいく
    16. 16. 2 4 1 3 5 時間 1.一番開始時間の早いものから見る 2.一番時間の短いものから見る 3.一番終了時間の早いものから見る今、その時点で一番○○なものを 貪欲法選んでいく
    17. 17. #!/usr/bin/perluse strict;use warnings; 終了時間でソート# 映画のリスト ↓my @movies = ([1,3], [2,5], [4,7], [6,9], [8,10]);@movies = sort { $a->[1] <=> $b->[1] } @movies; 順番に今見ることが出来my $ans = 0; るかを判定my $end = 0; # 前回見た映画の終了時刻 ↓for my $movie (@movies) {    if ($movie->[0] > $end) { 見れるものがあれば見る        $ans++;        $end = $movie->[1];    }} 計算量はO(n)print "ans: ", $ans, "n";
    18. 18. #!/usr/bin/perluse strict;use warnings; 終了時間でソート# 映画のリスト ↓my @movies = ([1,3], [2,5], [4,7], [6,9], [8,10]);@movies = sort { $a->[1] <=> $b->[1] } @movies; 順番に今見ることが出来my $ans = 0; るかを判定my $end = 0; # 前回見た映画の終了時刻 ↓for my $movie (@movies) {    if ($movie->[0] > $end) { 見れるものがあれば見る        $ans++;        $end = $movie->[1];    }} 計算量はO(n)print "ans: ", $ans, "n"; 仕事も恋も貪欲さが大事
    19. 19. Case3:
    20. 20. Case3:「何でも食べていいんだよねっ? 何食べたら一番お腹いっぱいに なるかなー♪(・ ・)」
    21. 21. Case3:「何でも食べていいんだよねっ? 何食べたら一番お腹いっぱいに なるかなー♪(・ ・)」5万円まででお願いします (ヽ ω`)
    22. 22. n種類の料理のリストがある。各料理はpiの値段でviの量がある。X万円以内で一番量が多くなる料理の組み合わせを見つけよ。※ただし料理は1種類につき1回しか頼めない
    23. 23. i番目の料理を食べるか食べないかで総当たり → 計算量はO(2^n)
    24. 24. i番目の料理を食べるか食べないかで総当たり → 計算量はO(2^n) i番目の料理を食べる、食べない、に分解 食べた時 食べない時X-pi円でi番目以外の料 X円でi番目以外の料理で理で最も量を食べたい 最も量を食べたい
    25. 25. i番目の料理を食べるか食べないかで総当たり → 計算量はO(2^n) i番目の料理を食べる、食べない、に分解 食べた時 食べない時X-pi円でi番目以外の料 X円でi番目以外の料理で理で最も量を食べたい 最も量を食べたい 動的計画法
    26. 26. i番目の料理を食べるか食べないかで総当たり → 計算量はO(2^n) i番目の料理を食べる、食べない、に分解 食べた時 食べない時X-pi円でi番目以外の料 X円でi番目以外の料理で理で最も量を食べたい 最も量を食べたい 動的計画法 一つ前や一つ後を考えたときに相似形が出てくる ような問題はDPで解きやすい!
    27. 27. i番目(i=0∼n-1)までの料理をj万円以内で食べた時の量の最大値をdp[i+1][j]とおくi→i+1とするときの遷移を考えると、以下の漸化式が導ける
    28. 28. i番目(i=0∼n-1)までの料理をj万円以内で食 べた時の量の最大値をdp[i+1][j]とおく i→i+1とするときの遷移を考えると、以下の 漸化式が導ける dp[i][j] (j < v[i])dp[i+1][j] = max(dp[i][j], dp[i][j-p[i]]+v[i]) (それ以 外)
    29. 29. #!/usr/bin/perluse strict;use warnings;use List::Util qw(max);my $n = 4; 計算量はたかだかO(nX)my @p = (2, 1, 3, 2);my @v = (3, 2, 4, 2);my $X = 5;my @dp = ([0, 0, 0, 0, 0, 0]);for my $i (0..$n-1) {    for my $j (0..$X) {        if ($j < $p[$i]) {            $dp[$i+1][$j] = $dp[$i][$j];        }        else {            $dp[$i+1][$j]                = max($dp[$i][$j], $dp[$i][$j-$p[$i]] + $v[$i]);        }    }}print "max_v: ", $dp[$n][$X], "n";
    30. 30. #!/usr/bin/perluse strict;use warnings;use List::Util qw(max);my $n = 4; 計算量はたかだかO(nX)my @p = (2, 1, 3, 2);my @v = (3, 2, 4, 2);my $X = 5;my @dp = ([0, 0, 0, 0, 0, 0]);for my $i (0..$n-1) {    for my $j (0..$X) {        if ($j < $p[$i]) {            $dp[$i+1][$j] = $dp[$i][$j];        }        else {            $dp[$i+1][$j]                = max($dp[$i][$j], $dp[$i][$j-$p[$i]] + $v[$i]);        }    }}print "max_v: ", $dp[$n][$X], "n"; 過去の思い出は大切に
    31. 31. Case4:
    32. 32. Case4:「今度の旅行楽しみだねー♪でも 私最短距離で移動しないと怒っちゃうぞっ(o≧▽゚)o」
    33. 33. Case4:「今度の旅行楽しみだねー♪でも 私最短距離で移動しないと怒っ ちゃうぞっ(o≧▽゚)o」新幹線で(ry (;́ `)
    34. 34. n個の地点がある。各地点間の道路の距離が与えられた時、地点iから地点jまでの最短経路を求めよ。
    35. 35. 3 2 9 8 10 41 11 12 この問題は左図のようなグラフで表される7 5 (この場合は重み付き無向グラフ) 6 1.n以下の整数kを取る 2.(1∼k) (i,j)のグラフを考える 3.この時のi,j間の最短経路をpi,jとする 4.このグラフに地点k+1を加える 5.この時のi,j間の最短経路は以下のどちらか
    36. 36. 3 2 9 8 10 41 11 12 この問題は左図のようなグラフで表される7 5 (この場合は重み付き無向グラフ) 6 1.n以下の整数kを取る 2.(1∼k) (i,j)のグラフを考える 3.この時のi,j間の最短経路をpi,jとする 4.このグラフに地点k+1を加える 5.この時のi,j間の最短経路は以下のどちらか pi,jまたはpi,k+1+pk+1,j
    37. 37. 3 2 9 ワーシャルフロイド 8 10 41 11 12 この問題は左図のようなグラフで表される7 5 (この場合は重み付き無向グラフ) 6 1.n以下の整数kを取る 2.(1∼k) (i,j)のグラフを考える 3.この時のi,j間の最短経路をpi,jとする 4.このグラフに地点k+1を加える 5.この時のi,j間の最短経路は以下のどちらか pi,jまたはpi,k+1+pk+1,j
    38. 38. #!/usr/bin/perl $p[$i][$j]は、use strict;use warnings; 直通の道あり → 2点間の距離dmy $n = 12; 直通の道なし → (十分大きな数)my ($s, $g) = (2, 5);my @p = init_p(); $i == $j →0for my $k (1..$n) { で初期化する    for my $i (1..$n) {        for my $j (1..$n) {            if ($p[$i][$k] + $p[$k][$j] < $p[$i][$j]) {                $p[$i][$j] = $p[$i][$k] + $p[$k][$j];            }        }    }}print "ans: ", $p[$s][$g], "n"; 計算量はO(n^3)
    39. 39. #!/usr/bin/perl $p[$i][$j]は、use strict;use warnings; 直通の道あり → 2点間の距離dmy $n = 12; 直通の道なし → (十分大きな数)my ($s, $g) = (2, 5);my @p = init_p(); $i == $j →0for my $k (1..$n) { で初期化する    for my $i (1..$n) {        for my $j (1..$n) {            if ($p[$i][$k] + $p[$k][$j] < $p[$i][$j]) {                $p[$i][$j] = $p[$i][$k] + $p[$k][$j];            }        }    }}print "ans: ", $p[$s][$g], "n"; 計算量はO(n^3) ときには遠回りも必要(?)
    40. 40. Thank you very much for your attention.
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×