問題: 0,1,...,9 のいずれかの整数からなる有限長の数列(di)i∈{0,1,...,m−1}で、法Kで
100⋅d0+101⋅d1+...+10m−1⋅dm−1=0
を満たすようなものについて、数列の総和 d0+d1+...+dm−1の最小値を求めたい。
まず、各桁diは0,1,...,,9の代わりに非負整数全体で考えてよい。というのも、ある桁が10以上である場合、それより桁和が小さい数列で同じ数を与えるものが必ず存在する(例: 100⋅13+101⋅1 なら 100⋅3+101⋅2)ので最小値は変わらないからである。
さて、dp[l][x]を次のように定める: 100,101,102,...から(重複を許して)l個選んで足し合わせて整数xを作ることが可能ならdp[l][x]=1、そのような選び方が存在しないならdp[l][x]=0。このとき、dp[l][0]=1になるような最小のl>0が答えである。
dpの漸化式を与える。l個の和で作れる数は、l−1個の和で作れる数と100,101,102,...のいずれかの和で作られるので、
dp[l][x]=i=0⋁x(dp[l−1][x−i]∧dp[1][i])
と表すことができて、これは畳み込みの形になっている。ブール代数に特化した効率的な畳み込みアルゴリズムは見あたらなかったが、単純に(+,×)でFFTしたあと、1以上の数をすべて1に訂正すればよい。なお、実際に計算するにあたっては、1次元のdpに対してin-placeに更新できる。
入力の制約より、答えは9+9+9+9+9=45を超えないので、高々43回畳み込みすればよいことになる。オーダーで表すとO(Klog2K)。
kyopro_friendsさんに教えていただいた解法だが、ちゃんと理解したと思えるのに時間がかかった。というか、ブール代数上の畳み込みが普通のFFTでできるというのがいまだに不思議だったりする。
https://mathoverflow.net/questions/10237/does-the-convolution-theorem-apply-to-weaker-algebraic-structures
convolution theoremでググったら見つかったトピック。おもしろそう(難しそう)。
dpを
dp[x]:={1+∞(xが10の累乗)(それ以外)
と初期化して、畳み込み
dp[x]:=0≤i≤xmin(dp[x−i]+dp[i])
を繰り返すのでもできそう? (min,+)の畳み込みはFFTほど効率的にはできないらしいけど、こう書き下すと最短経路問題であることはわかりやすくなる。つまり、100,101,102,...,を足す操作を有向辺にしたとき、dp[x]は最終的に頂点0から頂点xへの最短経路長になるので、BFSでも求まる。ただ、これだと想定のオーダーに達してはいない。 +1と×10だけで十分というのを自然に導きたいけど……