これはダイナミックプログラミングソリューションの優れた問題です。与えられた長さの与えられた数字(0または1)で始まる文字列の数を返すメソッドを持つだけで十分です。長n
の桁数よりも0から始まり、メモ化1.
単純なPythonの溶液から始まる文字列の合計がある:
_c = {} # Cache
def C(d, n, ij):
if n <= 1:
return 1
if (d, n) not in _c:
_c[(d, n)] = sum(C(1-d, n-x, ij) for x in xrange(1, min(ij[d], n)+1))
return _c[(d, n)]
def B(n, i, j):
ij = [i, j] # Easier to index
_c.clear() # Clears cache
return C(0, n, ij) + C(1, n, ij)
print B(3, 1, 2)
print B(300, 10, 20)
結果は:
4
1896835555769011113367758506440713303464223490691007178590554687025004528364990337945924158
の値ので与えられた桁と長さは、反対の桁の値と長さが与えられた長さよりも小さいことに依存するが、解は長さによってますます値を計算することによっても得られる。 Pythonソリューション:
def D(n, i, j):
c0 = [1] # Initialize arrays
c1 = [1]
for x in xrange(1, n+1): # For each next digit calculate value
c0.append(sum(c1[x-y] for y in xrange(1, min(i, x)+1)))
c1.append(sum(c0[x-y] for y in xrange(1, min(j, x)+1)))
return c0[-1] + c1[-1] # Sum strings starting of length n with 0 and 1
print D(3, 1, 2)
print D(300, 10, 20)
後でC++で実装する方が簡単です。
100111と011100で'i 'と'j'とは何ですか? – Surt
再帰的な定式化では、再帰呼び出しが 'i'または' j'ネガティブのいずれかで、いつでも削除することができます。 –
100111ではi => 2、j> = 3です。 011100では、i => 2、j> = 3です。 (iとjは同じ後続の数字の最大値を表し、入力は2つのi、jと配列サイズnで構成されます) –