蓝桥杯 算法训练 K好数(DP C++)

题干要求

【思路分析】
题目的意思是,求2位四进制数(只有0 1 2 3这四个数字)中,K好数的个数是多少。

状态:定义DP数组,DP[i][j]表示共i位数且结尾数字是j的K好数的个数。
当i=1时,也就是数字位数是1时,所有的数字都是K好数,因为没有数字相邻的情况。但是因为开头数字是j,所以要注意第一个数字不能是0,所以赋值时从1开始,最大为k-1。

状态转移方程:dp[i][j]=(dp[i][j]+dp[i-1][q])。
其实就是从第一个数字开始,逐个找出后面的数字不能与前一个数字相邻的情况有多少种,直到i=l为止。
最后,将长度为l的以0,1,2……k-1结尾的K好数的个数加起来。


【题解代码】

#include<stdio.h>
#include<string.h>

int dp[105][105];
int main(){
    int k,l;
    while(scanf("%d%d",&k,&l)!=EOF){ // 循环语句内等价于~scanf() 
        memset(dp,0,sizeof(dp)); // 可有可无 
        /*void *memset(void *s, int ch, size_t n);
        函数解释:将s中当前位置后面的n个字节用ch替换并返回s。
        memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法*/

        for(int i=1;i<k;i++)//当数字位数为1时,从1开始,个数都是1,K好数就是i 
            dp[1][i]=1;
        for(int i=2; i<=l; i++){ // i控制位数 
            for(int j=0;j<k;j++){ // j是前一位,数字的取值范围是0~k-1 
                for(int q=0;q<k;q++){ // q是后一位,数字的取值范围是0~k-1 
                    if(j-q==1 || j-q==-1) continue;
                    dp[i][j]=(dp[i][j]+dp[i-1][q])%1000000007;
                }
            } 
        }    
        long long ans=0;
        for(int i=0;i<k;i++)
            ans+=dp[l][i];  // 位数为l的方案数加和 
        printf("%d\n",ans%1000000007);
    }
    return 0;
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值