x枚目まで見たときに総和がy以上になるようなカードの集合の総数をdp[x][y]とすると、漸化式は
dp[x][y]=dp[x−1][y]+dp[x−1][y−ax]
となる。ここで、N番目のカードとi番目のカードを入れ替えて同じDPをしたものをdpiとする。dpiについても同じ漸化式が成立し
dpi[N][y]=dpi[N−1][y]+dpi[N−1][y−ai]
順番を入れ替えてもN枚処理すれば同じ結果になるはずだからdp[N][y]=dpi[N][y]が成り立つ。したがって
dp[N][y]=dpi[N−1][y]+dpi[N−1][y−ai]
整理して
dpi[N−1][y]=dp[N][y]−dpi[N−1][y−ai]
という漸化式が立つ。i番目のカードを除いたとき和がy以上になるような集合の総数をf[i][y]とするとf[i][y]=dpi[N−1][y]だから
f[i][y]=dp[N][y]−f[i][y−ai]
dpを求めた後、さらにfについてDPできる。
カードiが不必要
⇔ カードiを含む和がK以上になるような集合と、カードiを含まない和がK以上になるような集合が一対一対応する
⇔f[i][K]=dp[N][K]−f[i][K]
だから、この等式が成立するようなiを数えればよい。
dpの値は64ビットに収まらないので、適当にmodをとって扱う。弱衝突耐性があれば十分なので32ビットでよさそう。だめなら複数modを組み合わせればよい。
戻すDPを覚えるために復習。
参考:
https://sen-comp.hatenablog.com/entry/2019/11/06/121325