前提・実現したいこと
AtCoder ABC169 F問題に関する質問です。
下記のプログラムを作成しましたが、TLEとなってしまいました。
どこを修正すれば良いかをお聞きしたいです。
27testfile中7WAとなっているようで、問題文中のtestfileに関しては正常に作動しました。
発生している問題・エラーメッセージ
TLE 時間超過
該当のソースコード
Python
1n,s = map(int, input().split()) 2a = list(map(int, input().split())) 3 4MOD = 998244353 5 6dp = [[0]*(s+1) for i in range(n+1)] #動的計画法を用いる 参照渡しによるバグを防ぐためリスト内包表記 7dp[0][0] = 1 8 9for i in range(n): 10 for ss in range(s+1): 11 if(ss >= a[i]): 12 dp[i+1][ss] = (dp[i][ss]*2 + dp[i][ss-a[i]])%MOD #非常に大きな数になると考えられるため先にMOD計算を行う 13 else: 14 dp[i+1][ss] = dp[i][ss]*2 % MOD 15 16print(dp[n][s])
試したこと
12行目について
dp[i+1][ss] = (dp[i][ss]*2 + dp[i][ss-a[i]])%MOD
↓
dp[i+1][ss] = (dp[i][ss]*2%MOD + dp[i][ss-a[i]])%MOD
としましたが、逆にTLEとなるケースが2つ増えてしまいました。
##以降はyudedaka67様のご回答を参考にさせていただき試した修正
二重配列の廃止
Python
1... 2dp = [[0]*(s+1) for i in range(n+1)] #動的計画法を用いる 参照渡しによるバグを防ぐためリスト内包表記 3↓ 4dp = [0]*(s+1) 5 6ループ部分を以下に変更 7for i in range(n): 8 for ss in range(s,-1,-1): 9 if(ss >= a[i]): 10 dp[ss] = (dp[ss]*2 + dp[ss-a[i]])%MOD #非常に大きな数になると考えられるため先にMOD計算を行う 11 else: 12 dp[ss] = dp[ss]*2 % MOD
→TLEとなるファイルが7から5に
###Numpyの導入
######numpy.zerosによるベクトル生成
これだけだと逆にimportする分TLEが増えてしまいました
######numpyのベクトルの整数倍を用いる
Python
1...for iの中身を修正 2ddp = dp * 2 3 for ss in range(s,-1,-1): 4 if(ss >= a[i]): 5 ddp[ss] += dp[ss-a[i]]%MOD #非常に大きな数になると考えられるため先にMOD計算を行う 6 dp = ddp % MOD
これでもTLEとなるようでした
######numpyのベクトルの加算を用いる
Python
1...for iの中身を修正 2ddp = dp * 2 % MOD 3ddp[a[i]:] += dp[:-a[i]] #非常に大きな数になると考えられるため先にMOD計算を行う 4dp = ddp % MOD
こうすることで1/S倍ほどになり、ACできました。
回答1件
あなたの回答
tips
プレビュー