yukicoder No420 mod2漸化式
考察
・まずは素直にを書き連ねてみる。
・が奇数の時にになっていることに着目する。
・つまり,を2進数で表現した時1が立っているビットの数がになる。
・はまでなので、はまでしかないことが分かる。
・を普通にからまで見て立っているビットをカウントしても計算量が多い。
・ここでは半分全列挙みたいなことをイメージする。
・は31ビットなので,15ビットと16ビットに分ける。
・つまり,からまで,から。
・あとはdp[立っているビット数]とかにカウントする。
・からまでの数で立っているビット数をa,からまでの数で立っているビット数をbとする。
・が31ビットの内立っているビットがの組み合わせが計算できる。
・総和はdp[立っているビット数]とsum[立っているビット数]を利用すれば計算可能。
ソースコード
変数名にdpとありますがcntとかcountの方が良かったですね。DPではないので。
X = int(input()) if X <= 31: dp1 = [0 for i in range(17)] dp2 = [0 for i in range(16)] sum1 = [0 for i in range(17)] sum2 = [0 for i in range(16)] for i in range(1 << 16): c = 0 for j in range(16): c += ((i >> j) & 1) sum1[c] += i dp1[c]+=1 for i in range(1 << 15): c = 0 for j in range(15): c += ((i >> j) & 1) sum2[c] += (i << 16) dp2[c]+=1 s = 0 t = 0 for i in range(17): for j in range(16): if i + j == X: s += dp1[i] * dp2[j] t += (dp1[i] * sum2[j]) + dp2[j] * sum1[i] print(s,t) else: print(0,0)