python蓝桥杯:K好数(15行代码)

主要思想:动态规划

作为一个只会遍历的沙雕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)
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值