主要思想:动态规划
作为一个只会遍历的沙雕pythoner,做这道题完全没有想到动态规划,即时看到提示说动态规划也不知道怎么弄,于是先想出了遍历的方法。
最沙雕想法
把L位的K进制数遍历一遍,写了一个针对K进制的加法,每次加一,再写了一个check函数。
如果满足K好数条件则答案数加一。
毫无疑问,垃圾想法超时了,结果倒是对的。
学聪明了一点
每次加1是很傻的,比如1000,一直加到1111才得到第一个4位的K好数。
于是直接在用check函数返回相邻数字的序号,直接在低位序号加1。比如1000 +1=1100,1100+1=1110
这样遍历就快多了,可是结果还是超时。
不过这想法还是有点价值的,记录下来。
def add_1(num,x,y=0):
num[y]+=1
if(num[y]<x):
return num
else:
for i in range(y,len(num)):
if num[i]==x and i!=(len(num)-1):
num[i]=0
num[i+1]+=1
if(num[i+1]<x):
break
elif i==(len(num)-1):
num[i]=0
num.append(1)
break
return num
def check(num):
for i in range(len(num)):
if i==0:
if abs(num[0] - num[1]) == 1:
return [0,0]
elif i==len(num)-1:
if abs(num[i] - num[i - 1]) == 1:
return [i-1,0]
elif abs(num[i]-num[i+1])==1:
return [i,0]
return [0,1]
def main():
K,L=input().split()
K=int(K)
L=int(L)
if L==1:
print(K)
exit()
num=[ 0 for i in range(L)]
num[-1]=1
ans=0
while(len(num)==L):
index,judge=check(num)
if judge:
ans+=1
add_1(num, K)
else:
add_1(num,K,index)
print(ans)
if __name__=='__main__':
main()
动态规划
看看上面的代码,又费时又复杂,复杂的代码解决简单的问题简直了,傻逼本傻了。
在看了别人22行代码就解决的时候才发现自己好傻啊。于是领悟了能用动态规划就一定要用。
本题与斐波那契数列并没有太大差别。
如求4进制3位的K好数数目。
创建4行3列的矩阵
纵坐标是从0 取到K-1,横坐标是0 到L
0 1 2 3
0 1 3 8
1 1 2 5
2 1 2 5
3 1 3 8
每一列的数目加起来,再减去第一行的数(以0开头的L位数),就是改列对应的几位K好数个数
如K=4,L=2,对应就是3+2+2+3-3=7
可以看到3位的K好数与2位的K好数有关,只需去掉相邻的那一行或两行,再加起来就是其对应的数目。
K好数15行代码如下:
K,L=list(map(int,input().split()))
num=[[0 for i in range(L)] for j in range(K)]
for i in range(K):
num[i][0]=1
for j in range(L-1):
for i in range(K):
tmp=0
for k in range(K):
if k==i or abs(k-i)!=1:
tmp+=num[k][j]
num[i][j+1]=tmp
ans=0
for i in range(1,K):
ans+=num[i][L-1]
print(ans%1000000007)