Donuts プロコンチャレンジ2014

Preview:

DESCRIPTION

Donuts プロコンチャレンジ2014 の解説です。 http://donuts-live2014.contest.atcoder.jp/ (コンテストページは事前申込者のみ入れます)

Citation preview

DONUTS プロコンチャレンジ2014 解説

株式会社Donuts 久野慎弥(@kuno4n)

おつかれさまでした!

問題A 勤怠管理

問題A

勤務データが与えられます

休憩時間を除いた勤務時間を出力して下さい

問題A 例

300, 500, 600, 800

→ 500-300 + 800-600 = 400 が答え

問題A 解答

n % 2 == 1 の場合 “error” を出力

そうでない場合 (a_2 - a_1) + (a_4 - a_3) + … を出力

http://jobcan.ne.jp/

問題B 7TH

問題B以下の条件を満たすnが与えられます

1 ≦ n < 10^18

n の各桁は{1, 2, 3, 4, 5, 6, 7}

以下の条件を満たす自然数の個数は?

n以下

各桁は{1, 2, 3, 4, 5, 6, 7}

7の倍数

問題B 例

n = 31

→ 7, 14, 21 の3つが答え

問題B 部分点解法

1 ≦ n < 10^5 で部分点

愚直に条件を満たす自然数を数えればOK

問題B 満点解法

1 ≦ n < 10^18 で満点

ヒント

問題B 満点解法

1 ≦ n < 10^18 で満点

ヒント

11~17のうち、7の倍数はいくつあるか?

問題B 満点解法

1 ≦ n < 10^18 で満点

ヒント

11~17のうち、7の倍数はいくつあるか?

34251~34257のうち、7の倍数はいくつあるか?

問題B 満点解法

1 ≦ n < 10^18 で満点

ヒント

11~17のうち、7の倍数はいくつあるか?

34251~34257のうち、7の倍数はいくつあるか?

どうみても1個

問題B 満点解法

34211~34277のうち、7の倍数はいくつあるか?

7個

11111~77777のうち、7の倍数はいくつあるか?

7×7×7×7個

問題B 満点解法

3546以下を考えてみる

問題B 満点解法

3546以下を考えてみる

3541, 3542, 3543, 3544, 3545, 3546

→3542の1個

問題B 満点解法

3546以下を考えてみる

353*, 352*, 351* 000*

→ 7^0 × 4個

問題B 満点解法

3546以下を考えてみる

34**, 33**, 32**, 31** 00**

→ 7^1 × 5個

問題B 満点解法

3546以下を考えてみる

2***, 1***, 0***

→ 7^2 × 3個

問題C ソーシャルゲーム

問題C

1≦n≦100000 個からなる数列が与えられます

部分列の和が最大になる箇所の和を求めて下さい

問題C 例

3, -4, 2, 3, -1, 2, -1

→ 2, 3, -1, 2, の和6が答え

問題C 部分点解法

1 ≦ n ≦ 3000 で部分点

O(n^2)で全ての部分列を調べ上げればOK

O(n^3)にならないように注意

問題C 満点解法

1 ≦ n ≦ 10^5 で満点

O(n)の方法を考えよう

問題C 満点解法

左から順番に足していく

問題C 満点解法

左から順番に足していく

問題C 満点解法

左から順番に足していく

問題C 満点解法

あるとき、和がマイナスになった

問題C 満点解法

途中からの和は絶対にマイナス

問題C 満点解法

途中からの和は絶対にマイナスなぜなら、それまでの和がプラスだから

問題C 満点解法

なので、和がマイナスになったら、

問題C 満点解法

なので、和がマイナスになったら、それまでのことは忘れて新しく足し始めればよい

問題C 満点解法

なので、和がマイナスになったら、それまでのことは忘れて新しく足し始めればよい

問題C 満点解法

なので、和がマイナスになったら、それまでのことは忘れて新しく足し始めればよい

問題C 満点解法

3, -4, 2, 3, -1, 2, -1

sum 0 result -1000

問題C 満点解法

3, -4, 2, 3, -1, 2, -1

sum 3 result 3

問題C 満点解法

3, -4, 2, 3, -1, 2, -1

sum -1 result 3

問題C 満点解法

3, -4, 2, 3, -1, 2, -1

sum 0 result 3

↑マイナスになったので、リセット

問題C 満点解法

3, -4, 2, 3, -1, 2, -1

sum 2 result 3

問題C 満点解法

3, -4, 2, 3, -1, 2, -1

sum 5 result 5

問題C 満点解法

3, -4, 2, 3, -1, 2, -1

sum 4 result 5

問題C 満点解法

3, -4, 2, 3, -1, 2, -1

sum 6 result 6

問題C 満点解法

3, -4, 2, 3, -1, 2, -1

sum 5 result 6

問題C 満点解法

3, -4, 2, 3, -1, 2, -1

result 6

maximum subset sum (mss: 最大部分列和)

といいます

問題D サバゲー

問題D

見分けのつくボールがn個

見分けの付かない箱がm個

1 ≦ n ≦ 1000, 1 ≦ m ≦ n

どの箱にも最低1個入れる入れ方は?

問題D 例

n = 3, m = 2

1 2 3

問題D 例3通り

1 2 3

1 2 3

1 3 2

問題D 部分点解法

箱が2つ で部分点

1 2 3 4 ……

問題D 部分点解法

1番のボールを入れれば箱の見分けがつくので、

1

2 3 4 ……

問題D 部分点解法

あとは

1 23

4 ……

2^(n-1)

問題D 部分点解法

ただし、全て同じ箱はNG

123

4 ……

2^(n-1) - 1

問題D 満点解法

1 ≦ n ≦1000 1 ≦ m ≦ n で満点

1 2 3 n……

……

n-1

問題D 満点解法

n-1 個目まで入れ終わった状態を考える

123

n

……n-1

問題D 満点解法

m個の箱が全部埋まっている状態なら、

123

n

……n-1

問題D 満点解法

n番目のボールはm通りの入れ方がある

123

n

……n-1

問題D 満点解法

m-1個の箱が埋まっている状態なら、

12

3

n

……n-1

問題D 満点解法

「入っていない箱に入れる」という1通りしかない

12

3

n

……n-1

問題D 満点解法埋まっている箱がm-2個以下なら、

12

3

n

……n-1

問題D 満点解法埋まっている箱がm-2個以下なら、

12

3

n

……n-1

「n個のボールをm個の箱に入れる」事はできない

問題D 満点解法

n個のボールをm個の箱に入れる入れ方

123n

……n-1

S(n, m)は、

問題D 満点解法

n個のボールをm個の箱に入れる入れ方

123n

……n-1

S(n, m) = S(n-1, m)×m + S(n-1, m-1)

問題D 満点解法

n個のボールをm個の箱に入れる入れ方

123n

……n-1

S(n, m) = S(n-1, m)×m + S(n-1, m-1)

第二種スターリング数

問題D 別解

123n

……n-1

「箱にも区別がつく」と考えて、 最後にm! で割ってもOK

(modが素数なので逆元が使えます)

問題D おまけボール 箱 最低1個入れる 高々1個入れる 入れ方に制限なし

区別が付く 区別が付く 1 2 3

区別が付く 区別が付かない 4 5 6

区別が付かない 区別が付く 7 8 9

区別が付かない 区別が付かない 10 11 12

問題D おまけボール 箱 最低1個入れる 高々1個入れる 入れ方に制限なし

区別が付く 区別が付く 1 2 3

区別が付く 区別が付かない 4 5 6

区別が付かない 区別が付く 7 8 9

区別が付かない 区別が付かない 10 11 12

第二種スターリング数はここ

問題D おまけボール 箱 最低1個入れる 高々1個入れる 入れ方に制限なし

区別が付く 区別が付く 1 2 3

区別が付く 区別が付かない 4 5 6

区別が付かない 区別が付く 7 8 9

区別が付かない 区別が付かない 10 11 12

写像12相http://kuno4n.hateblo.jp/entries/2013/12/14

問題E お菓子やさん

問題E

頂点数nの重み付き有向グラフ

1 ≦ n ≦ 16

いくつか辺を取り除いて閉路を無くしたとき、残った重み合計を最大にするには?

問題E 例

30

10

20

問題E 例

30

10

20

result: 50

問題E 例

3

23 3

3

問題E 例

3

23 3

3

result: 12

問題E だめな例

貪欲にやってもうまくいきません

例:閉路を見つけたら一番小さい辺を消す

例:一番大きい辺から採用する

問題E だめな例

2

32 2

2

こういうので死にます

問題E だめな例

2

32 2

2

中央の辺を消すのが正解

問題E 部分点解法

閉路のない有向グラフ ということは

問題E 部分点解法

1

3

2

5

閉路のない有向グラフ ということは

4トポロジカルソート ができる

問題E 部分点解法

1

3

2

5

全ての並び順をためす

4

1→2→3→4→5 1→2→3→5→4 …… 5→4→3→2→1

問題E 部分点解法

1

3

2

5

全ての並び順をためす

4

1→2→3→4→5 1→2→3→5→4 …… 5→4→3→2→1

「戻り辺」があったら 必ず消す

問題E 部分点解法

1

3

2

54

O(n! × n)

n ≦ 8なら余裕

c++ならnext_permutationとか使えます

問題E 満点解法

1

3

2

4

n ≦ 16 で満点

部分点解法の考え方が使えます

問題E 満点解法

1

3

2

45

「5」を付け加えるときに、 1~4の並び順が 1→2→3→4 だろうと 3→1→4→2 だろうと関係ない。 (最大の重みだけ知れればOK)

問題E 満点解法

5

1~4の結果をまとめて、 5を付け加える。

1~4の結果

問題E 満点解法

5

1~4の結果をまとめて、 5を付け加える。

1~4の結果

動的計画法

問題E 満点解法

5

1~4の結果n ≦ 16 なので、bitDP

{1,2,3,4}の結果を知るには、{1,2,3}, {1,2,4}, {1,3,4}, {2,3,4}の結果を知ればよい。

{1,2,3}の結果を知るには、{1,2}, {2,3}, {1,3}の結果を知ればよい。

O(2^n × n)

ありがとうございました!