2020年1月24日金曜日

ARC 028 D - 注文の多い高橋商店

とりあえず「簡単すぎる」ほうの問題を解く。dp[x][y]:=\mathrm{dp}[x][y] :=商品を最初のxx種類からちょうどyy個選ぶ方法の総数、とする。dp[x][y]=d[x1][y]+dp[x1][y1]+...+dp[x1][yax]\mathrm{dp}[x][y] = d[x-1][y] + \mathrm{dp}[x-1][y-1] + ... + \mathrm{dp}[x-1][y-a_{x}]と遷移できるが、これでは間に合わないので累積和を考える。つまりDP[x][y]:=\mathrm{DP}[x][y] :=商品を最初のxx種類からyy以下選ぶ方法の総数としたとき、

DP[x][y]=dp[x][0]+dp[x][1]+...+dp[x][y] \mathrm{DP}[x][y] = \mathrm{dp}[x][0]+ \mathrm{dp}[x][1] + ... + \mathrm{dp}[x][y] DP[x][y]=DP[x][y1]+dp[x][y] \mathrm{DP}[x][y] = \mathrm{DP}[x][y-1] + \mathrm{dp}[x][y] dp[x][y]=DP[x1][y]DP[x1][yax1] \mathrm{dp}[x][y] = \mathrm{DP}[x-1][y] - \mathrm{DP}[x-1][y-a_x-1]

が成り立つので、

DP[x][y]=DP[x][y1]+DP[x1][y]DP[x1][yax1] \mathrm{DP}[x][y] = \mathrm{DP}[x][y-1] + \mathrm{DP}[x-1][y] - \mathrm{DP}[x-1][y-a_x-1]

というO(1){O}(1)の遷移を導ける。ここからyyを一個ずらした漸化式DP[x][y1]=DP[x][y2]+DP[x1][y1]DP[x1][yax2]\mathrm{DP}[x][y-1] = \mathrm{DP}[x][y-2] + \mathrm{DP}[x-1][y-1] - \mathrm{DP}[x-1][y-a_x-2]を引くと、dp\mathrm{dp}についても同じ形の漸化式が得られる:

dp[x][y]=dp[x][y1]+dp[x1][y]dp[x1][yax1] \mathrm{dp}[x][y] = \mathrm{dp}[x][y-1] + \mathrm{dp}[x-1][y] - \mathrm{dp}[x-1][y-a_x-1]

これで簡単なほうの問題が解けた。

さて、ここでNN番目の商品とii番目の商品を入れ替えて同じDPをすることを考える。この配列をdpi\mathrm{dp}_iとするとき、dpi\mathrm{dp}_idp\mathrm{dp}と同じ遷移で求まり、しかもNN種類の商品を処理すると同じ値になるはずである。つまり、任意の個数yyについてdp[N][y]=dpi[N][y]\mathrm{dp}[N][y] = \mathrm{dp}_i[N][y]が成り立つ。したがって

dpi[N][y]=dpi[N][y1]+dpi[N1][y]dpi[N1][yai1] \mathrm{dp}_i[N][y] = \mathrm{dp}_i[N][y-1] + \mathrm{dp}_i[N-1][y] - \mathrm{dp}_i[N-1][y-a_i-1]

という等式から

dp[N][y]=dp[N][y1]+dpi[N1][y]dpi[N1][yai1] \mathrm{dp}[N][y] = \mathrm{dp}[N][y-1] + \mathrm{dp}_i[N-1][y] - \mathrm{dp}_i[N-1][y-a_i-1]

が導け、整理すると

dpi[N1][y]=dp[N][y]dp[N][y1]+dpi[N1][yai1] \mathrm{dp}_i[N-1][y] = \mathrm{dp}[N][y] - \mathrm{dp}[N][y-1] + \mathrm{dp}_i[N-1][y-a_i-1]

となる。ii番目の商品を除いた場合に全体でちょうどyy個の商品を選ぶ方法の総数をf[i][y]f[i][y]とするとき、f[i][y]=dpi[N1][y]f[i][y] = \mathrm{dp}_i[N-1][y]であるから、

f[i][y]=dp[N][y]dp[N][y1]+f[i][yai1] f[i][y] = \mathrm{dp}[N][y] - \mathrm{dp}[N][y-1] + f[i][y-a_i-1]

となり、ffについてDPすればクエリにO(1){O}(1)で答えられることになる。O(NM+Q){O}(NM + Q)


戻すDPというらしい。

参考:
http://sigma425.hatenablog.com/entry/2015/07/31/121439