蓝桥杯 K好数 算法训练 (动态规划DP)

来源:互联网 发布:王者荣耀用户数据分析 编辑:程序博客网 时间:2024/05/18 03:37

传送门:K好数



题目大意

如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数。求L位K进制数中K好数的数目。例如K = 4,L = 2的时候,所有K好数为11、13、20、22、30、31、33 共7个。由于这个数目很大,请你输出它对1000000007取模后的值。 (1 <= K,L <= 100)



思路

题目提示用 DP ,那就用 DP来搞喽。


我们设 dp[i][j] 表示 i 位的最高位为 j 的 K 进制数有多少个。这里 i 的取值为 1<= i <= L ,j 的取值为 0<= j < K。


我们先从 1 位 K 进制数开始处理,最高位为 0~k-1 的数有 1 个。然后考虑至少 2 位 K 进制数,最高位为 j 的话,则次高位不可以是 j+1 或 j-1,其他的都 OK ,所以dp[i][j] = sum( dp[i-1][x] ) 其中 sum 是求和,x != j+1 且 x != j-1。


需要注意的是,i 位的 K 进制数最高位不能为 0,否则就没意义了,所以在最后求和的时候不算入 j=0 的情况即可。



代码:

#include<stdio.h>#include<string.h>typedef long long LL;int main(){int x,y,z,k,l,dp[105][105];int mod=1e9+7;scanf("%d%d",&k,&l);memset(dp,0,sizeof(dp));for(x=0;x<k;x++) dp[1][x]=1; //只有一位的情况 for(x=2;x<=l;x++) //多少位 for(y=0;y<k;y++) //最高位 {dp[x][y]=dp[x-1][y]; //次高位为 y的情况 /*次高位不等于 y+1 和 y-1*/for(z=0;z<=y-2;z++) dp[x][y]=(dp[x][y]+dp[x-1][z])%mod;for(z=y+2;z<k;z++) dp[x][y]=(dp[x][y]+dp[x-1][z])%mod;}int ans=0;for(x=1;x<k;x++) //注意不算入最高位为 0的情况 ans=(ans+dp[l][x])%mod;printf("%d\n",ans);return 0;}


最后想花点时间吐槽一下蓝桥杯。你题目有错别字也就罢了,数据有的都不对是闹哪样啊?刚开始不对也就罢了,难道就不知道把错误改正吗?淦!!!

原创粉丝点击