def recursion_zenik(n,k,path=[],debug=False):
if path and max(path)-min(path)>k:
if debug:
print('Zenik rule fail:',path)
return 0
if n==0:
if debug:
print('Success:',path)
return 1
return sum(recursion_zenik(n-i,k,path+[i]) for i in range(1,n+1))
def matrix_zenik(n,k, debug = False):
matrix = []
for step in range(n+1):
line = [0]*(step+2)
matrix.append([line[:] for _ in range(n+1)])
matrix[step][step][step] = 1 #we have 1 way to step from the land on each step
for step_from in range(1,n):
for step_to in range(step_from+1,n+1):
for min_i in range(1,step_from+2):
for max_i in range(min_i,min(min_i+k,step_from+1)+1):
min_to_write = min(min_i,step_to-step_from)
max_to_write = max(max_i,step_to-step_from)
if max_to_write-min_to_write<=k:
matrix[step_to][min_to_write][max_to_write] += matrix[step_from][min_i][max_i]
if debug:
for step in range(n+1):
print(step,':',',\n'.join(str(line) for line in matrix[step]))
return sum(sum(line) for line in matrix[n])
def check_equal_rec_mat(s):
for n in range(1,s):
for k in range(1,s):
rec = recursion_zenik(n,k)
mat = matrix_zenik(n,k)
if rec!=mat:
print('\nFAIL: n=',n,'k=',k,'rec=',rec,'mat=',mat)
else:
print('OK',end=' ')
print()
#print('Result =',recursion_zenik(4, 2, debug=False))
#print('Result =',matrix_zenik(4,2,debug=True))
#check_equal_rec_mat(15)
import time
t = time.clock()
print(matrix_zenik(100,100))
print('time = ',time.clock()-t)
ZGVmIHJlY3Vyc2lvbl96ZW5payhuLGsscGF0aD1bXSxkZWJ1Zz1GYWxzZSk6CiAgICBpZiBwYXRoIGFuZCBtYXgocGF0aCktbWluKHBhdGgpPms6CiAgICAgICAgaWYgZGVidWc6CiAgICAgICAgICAgIHByaW50KCdaZW5payBydWxlIGZhaWw6JyxwYXRoKQogICAgICAgIHJldHVybiAwCiAgICBpZiBuPT0wOgogICAgICAgIGlmIGRlYnVnOgogICAgICAgICAgICBwcmludCgnU3VjY2VzczonLHBhdGgpCiAgICAgICAgcmV0dXJuIDEKICAgIHJldHVybiBzdW0ocmVjdXJzaW9uX3plbmlrKG4taSxrLHBhdGgrW2ldKSBmb3IgaSBpbiByYW5nZSgxLG4rMSkpCgpkZWYgbWF0cml4X3plbmlrKG4saywgZGVidWcgPSBGYWxzZSk6CiAgICBtYXRyaXggPSBbXQogICAgZm9yIHN0ZXAgaW4gcmFuZ2UobisxKToKICAgICAgICBsaW5lID0gWzBdKihzdGVwKzIpCiAgICAgICAgbWF0cml4LmFwcGVuZChbbGluZVs6XSBmb3IgXyBpbiByYW5nZShuKzEpXSkKICAgICAgICBtYXRyaXhbc3RlcF1bc3RlcF1bc3RlcF0gPSAxICN3ZSBoYXZlIDEgd2F5IHRvIHN0ZXAgZnJvbSB0aGUgbGFuZCBvbiBlYWNoIHN0ZXAKICAgIAogICAgZm9yIHN0ZXBfZnJvbSBpbiByYW5nZSgxLG4pOgogICAgICAgIGZvciBzdGVwX3RvIGluIHJhbmdlKHN0ZXBfZnJvbSsxLG4rMSk6CiAgICAgICAgICAgIGZvciBtaW5faSBpbiByYW5nZSgxLHN0ZXBfZnJvbSsyKToKICAgICAgICAgICAgICAgIGZvciBtYXhfaSBpbiByYW5nZShtaW5faSxtaW4obWluX2krayxzdGVwX2Zyb20rMSkrMSk6ICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIG1pbl90b193cml0ZSA9IG1pbihtaW5faSxzdGVwX3RvLXN0ZXBfZnJvbSkKICAgICAgICAgICAgICAgICAgICBtYXhfdG9fd3JpdGUgPSBtYXgobWF4X2ksc3RlcF90by1zdGVwX2Zyb20pCiAgICAgICAgICAgICAgICAgICAgaWYgbWF4X3RvX3dyaXRlLW1pbl90b193cml0ZTw9azoKICAgICAgICAgICAgICAgICAgICAgICAgbWF0cml4W3N0ZXBfdG9dW21pbl90b193cml0ZV1bbWF4X3RvX3dyaXRlXSArPSBtYXRyaXhbc3RlcF9mcm9tXVttaW5faV1bbWF4X2ldCiAgICAgICAgICAgICAgICAgICAgCiAgICBpZiBkZWJ1ZzoKICAgICAgICBmb3Igc3RlcCBpbiByYW5nZShuKzEpOgogICAgICAgICAgICBwcmludChzdGVwLCc6JywnLFxuJy5qb2luKHN0cihsaW5lKSBmb3IgbGluZSBpbiBtYXRyaXhbc3RlcF0pKQogICAgcmV0dXJuIHN1bShzdW0obGluZSkgZm9yIGxpbmUgaW4gbWF0cml4W25dKQoKZGVmIGNoZWNrX2VxdWFsX3JlY19tYXQocyk6CiAgICBmb3IgbiBpbiByYW5nZSgxLHMpOgogICAgICAgIGZvciBrIGluIHJhbmdlKDEscyk6CiAgICAgICAgICAgIHJlYyA9IHJlY3Vyc2lvbl96ZW5payhuLGspCiAgICAgICAgICAgIG1hdCA9IG1hdHJpeF96ZW5payhuLGspCiAgICAgICAgICAgIGlmIHJlYyE9bWF0OgogICAgICAgICAgICAgICAgcHJpbnQoJ1xuRkFJTDogbj0nLG4sJ2s9JyxrLCdyZWM9JyxyZWMsJ21hdD0nLG1hdCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHByaW50KCdPSycsZW5kPScgJykKICAgIHByaW50KCkKCiNwcmludCgnUmVzdWx0ID0nLHJlY3Vyc2lvbl96ZW5payg0LCAyLCBkZWJ1Zz1GYWxzZSkpCiNwcmludCgnUmVzdWx0ID0nLG1hdHJpeF96ZW5payg0LDIsZGVidWc9VHJ1ZSkpCiNjaGVja19lcXVhbF9yZWNfbWF0KDE1KQppbXBvcnQgdGltZQp0ID0gdGltZS5jbG9jaygpCnByaW50KG1hdHJpeF96ZW5paygxMDAsMTAwKSkKcHJpbnQoJ3RpbWUgPSAnLHRpbWUuY2xvY2soKS10KQo=