実現したいこと
ここに実現したいことを箇条書きで書いてください。
- AtCoder ABC281 D - Max Multiple のWAを解消したい(02_rnd_04.txtのみ通りません。)
問題: https://atcoder.jp/contests/abc281/tasks/abc281_d
提出: https://atcoder.jp/contests/abc281/submissions/38906904
該当のソースコード
コード内にコードの説明を追加しました。
Python
1import sys 2import copy 3 4 5stdin = sys.stdin 6 7ni = lambda: int(ns()) 8na = lambda: list(map(int, stdin.readline().split())) 9ns = lambda: stdin.readline().rstrip() 10 11N, K, D = na() 12A = na() 13 14old = [(-1, []) for _ in range(D)] # Dで割った余りnそれぞれに対し、old[n] = ((Dで割った余りがnになるもののうち最大のもの), (最大となるときに用いたAの要素のインデックス)) 15old[0] = (0, []) # 0個のAの要素を用いたときで初期化 16 17for i in range(K): # DPを用いて、1〜K個のAの要素を用いたときでoldを更新していく。 18 new = [(-1, []) for _ in range(D)] 19 for d, m in old: 20 if d == -1: 21 continue 22 for j, a in enumerate(A): 23 if j in m: 24 continue 25 dn = d + a 26 if new[dn % D][0] < dn: 27 mn = copy.copy(m) 28 mn.append(j) 29 new[dn % D] = (dn, mn) 30 old = new 31 32 33print(old[0][0])
補足情報(FW/ツールのバージョンなど)
下記にテストケースが公開されています。02_rnd_04.txtのみ通りません。エッジケースでもなくただのランダムケースなので詰んでいます。
02_rnd_04.txtの内容を記載します。
input
198 70 22 217096559 766405565 804429679 84257473 574087672 682206981 926560922 600021616 682445370 652604027 201314351 927105156 679340342 660728814 383622075 285589314 182284197 687206515 31124020 27662047 326058514 156545435 590310385 192593521 321700744 777412132 990038735 806894778 96122313 176239779 547637388 323210461 35653200 511887643 976452260 242864826 279740888 181955557 920559861 372723449 447181609 826720343 622156745 203298686 710918650 838194246 580762090 707052188 907287756 341123612 41476794 707952930 598154395 342610123 417976248 337559654 769913440 196375870 173337362 176944354 592907291 604654771 385486788 326640935 642680254 437170554 638572318 881717794 951978982 908566479 797638095 237171256 931168386 791228334 221969252 857964611 52734986 410850715 327359101 129251286 924817124 365840393 327644854 975752491 695542942 455368048 736391473 399932810 647635285 503985731 867195563 505817949 801848394 115840385 846351364 32299388 887257649 56307152
out
145732572468
AtCoder ABC281の問題は、AからExまで8問ありますので、D - Max Multipleであることを明記してください。
また、問題へのリンクのご提示もお願いします。
追記させていただきました。ご回答の方よろしくお願いいたします。
読んでいませんが、おそらく動的計画法で解いているんですよね?
ならば AC になるコードを取ってきて、今のコードとそのコードで二つの配列を作り、逐次比較してみれば何かわかるんじゃないでしょうか。
if new[dn % D][0] < dn:
この部分なのですが、new[dn % D][0] == dn が成り立つ場合は、その組み合わせもチェックする必要があるのではないでしょうか。
Zuishinさん、試みてみます。ありがとうございます。
melianさん、コメントありがとうございます。
23行目
```python
if j in m:
continue
```
において暫定的にS内に含まれているAの要素との重複をチェックしていること、及びご指摘の、new[...][0]に格納される整数(言い換えると、dnが代入される部分です)が同じ場合にはnew[...][1]はどちらでも良いことから、ここはチェックをしないことにしています。こちら、私の認識間違いがございましたら教えていただけますと幸いです。
dn の最大値が複数ある場合、それらのインデックスを j1, j2 とすると以下の new[dn%D][1] を作成して、それぞれで DP を実行する必要があるのではないでしょうか。
new[dn%D][1].append(j1) # j1 を追加したもの(j2 は含まれていない)
new[dn%D][1].append(j2) # j2 を追加したもの(j1 は含まれていない)
AC になる方法を尋ねているのではなく、どうしてこれでうまくいかないかを知りたいということですが、既存の回答の通り切り捨ててはいけないものを切り捨てています。
問題が長いとわかりにくいと思うので、簡単なものを作ってみました。
6 4 4
7 4 5 5 5 2
以上は、4 + 5 + 5 + 2 = 16 が答えになりますが、質問のコードでは -1 を出力します。
各周の new を出力させてみると、次のようになります。
[(4, [1]), (5, [2]), (2, [5]), (7, [0])]
[(12, [2, 0]), (9, [1, 2]), (10, [2, 3]), (11, [1, 0])]
[(16, [2, 0, 1]), (17, [2, 0, 3]), (14, [2, 0, 5]), (15, [2, 3, 4])]
[(-1, []), (21, [2, 0, 1, 3]), (22, [2, 0, 3, 4]), (19, [2, 0, 3, 5])]
3 周目に (14, [2, 0, 5]) とありますが、ここで要素 5 の 2 を使っているために、14 に 2 を足すことができなくなり、16 という正解が出なくなっています。
質問のコードで不正解になるデータは多くあり、AtCoder で WA が 1 つしか出なかったのはたまたまということになります。
うまくいかない理由の主なものは、ループの順番を間違えていることです。
K を最も外側で回していますが、ここでは A を回すべきでしょう。
この質問者、前の質問でも教えてもらったのに自己解決してるな。
教えてもらうのが悔しいなら聞かなきゃいいのに。
Zuishinさん、前回の質問に関してですが、18:26に追加のコメントがあり18:29に自己解決としています。これはそれ以前のコメントがわかりにくく参考にならなかったため自分で試行錯誤をしたのちに自己解決でき、それを投稿する直前に追加のコメントがあった次第となります。最初から追加のコメントの内容が記載されており参考になったのであればもちろんベストアンサーにしましたが、最初のコメントが投げやりで参考になっていなかったため自己解決にした次第です。ご理解よろしくお願いいたします。
そのコメントは追加質問の 5 分後。それから 3 分後の自己解決。
質問者にとってわかりにくいかどうかなんて質問者以外にわかるわけないし、8 分で自己解決するのも不自然です。
投げやりとは言うけど、WA になるケースを具体的に示した回答なので、不親切とは思いません。
2 と 10 のどちらが大きくなるかというケースを示せば、よほどの初心者ではない限り理解できるじゃありませんか。
むしろなぜこれでわからないのか疑問です。
追加質問を投げている間にも自分で試行錯誤しているなんてことは余程の初心者でもわかるとおもいますが、、、
余程の初心者はstrのままで数値評価ができないということに気づかないんですよ。当時の自分はそれぐらい余程の初心者でした。その上で試行錯誤をして自分で突き止めた次第です。これだけ説明したらさすがのあなたでもわかりますでしょうか?
また、他のコメントにも全て返信させていただいている通り、私は他人に教わることでプライドが傷つくとかそういったことを考えたことすらございませんでした。Zuishinさんはプライドが傷ついて当然だという価値観で生きていらっしゃるのですね。楽しそうで羨ましいです。
自己解決できるのにあの回答で理解できない理由がわからないという意味で、初心者は関係ないですね。
このあなたの反応から、とにかく意味不明なプライドがあることがわかります。
まあ羨ましいなら、回答がついて数分経つ前に自己解決できるようになればいいと思いますよ。
回答3件
あなたの回答
tips
プレビュー