問題文と制約を見てO(Nmaxsi)で解くしかないという気持ちになる。順番が固定されていないが、固定されていないと難しすぎるのでその方法を探す。
丈夫さについても重さについても、大きいブロックは下に置いたほうが良いはずなので、まずはsi+wiで降順にソートするという案を思いつく。実際、それでよいことが証明できる。有効なタワーが与えられたとし、丈夫さと重さが下のブロックから(s1′,w1′),(s2′,w2′),...,(sk′,wk′)になっているとする。隣り合うブロックでsi′+wi′≤si+1′+wi+1′が成り立つペアがあったとき、ブロックiとブロックi+1を入れ替えても有効なタワーのままであることが示せれば十分である。
ブロックiとi+1を入れ替えたとき、1,...,i−1番目とi+2,...,k番目のブロックにかかる重さは変わらず、i番目だったブロックにかかる重さは減るので、i+1番目だったブロックについてだけ考えればよい。このブロックに以前掛かっていた重さをGとすると、新しい配置で掛かる重さはG+wi′になる。ところでi番目だったブロックは丈夫さsi′で重さG+wi+1′に耐えていたのでsi′−wi+1′≥Gが成り立つ。si′+wi′≤si+1′+wi+1′からsi+1′−wi′≥si′−wi+1′≥Gが従い、丈夫さsi+1′でG+wi′に耐えられることがわかる。従って、ブロックiとi+1を入れ替えてもタワーは有効である。□
si+wiの降順に並んだタワーだけ考えればよいことがわかったので、あとは端からDPすればよい。dp[x][y]:= ブロック1,2,...,xから作れて、耐えられる重さがyであるようなタワーの価値の最大値、とする。
dp[x+1][min(y−wx+1,sx+1)]←max(∗,dp[x][y]+vx+1)
dp[x+1][y]←max(∗,dp[x][y])
と遷移すればよい。(∗は左辺)