K好数(动态规划求解)

问题描述

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

输入包含两个正整数,K和L。
输出格式
输出一个整数,表示答案对1000000007取模后的值。
样例输入
4 2
样例输出
7
数据规模与约定

对于30%的数据,KL <= 106;

对于50%的数据,K <= 16, L <= 10;

对于100%的数据,1 <= K,L <= 100。

解答:
找规律找到头炸。。。。。。
无奈还是上网参考了大神的动态规划的代码

代码如下:

    import java.util.Scanner;  
class Main{  
    static int MOD=1000000007 ;     
    public static void main(String[] args) {  
         Scanner sc = new Scanner(System.in);  
         int k = sc.nextInt();  
         int l = sc.nextInt();  
         int dp[][] = new int[101][101];  //dp[i][j]表示i位数,最后一位是j的k好数的个数,其中f[i][j] = sum(f[i-1][j]);
         for (int i = 0; i < k; i++) {  
             dp[1][i] = 1;  //如果是一位数,在第一位上取i(i=[0,k-1])的情况就只有一种
         }  
         for (int i = 2; i <=l; i++) {  //两位数以上的判断
             for (int j = 0; j < k; j++) {  
                 for (int j2 = 0; j2 < k; j2++) {  
                     if(j2 != j-1 && j2 != j+1){  //判断j2是否与j不相邻
                         dp[i][j] += dp[i-1][j2]; 
                            /*  
                             * dp[i][j]表示在第i位上放j(j=[0,k-1])的所有情况的个数。
                             * 而此时的for循环中的dp[i-1][j2],表示在第i-1位上的数字,并[0,(k-1)]中寻找,若与j不相邻,则给dp[i][j]加上dp[i-1][j2]的数值。
                             * dp[i-1][j2]中的数值表示,前一位(也就是i-1位)上,在符合前后不相邻的情况下,该位数值为j2的所有情况的个数。
                             */
                          dp[i][j] %= MOD;  //由于最终要取余,所以此处取余不影响结果,
                                              //此处直接取余是为了减小数值,加快运算 
                    }  
                }  
            }  
        }  
        int sum = 0;  
        for (int i = 1; i < k; i++) {  
            sum+= dp[l][i];  
            sum %= MOD;  
        }  
    System.out.println(sum);       
    }  
}  
/*  
 * K好数,k = 4    
位数      该位取值        前一位可取个数 计次(part)                合计                  减去数目                           
1       0~k-1                                              4                   0

2       0           k-1             Q10 = k-1               Q10+Q11+Q12+Q13     3  00 02 03 k-1
        1           k-2             Q11 = k-2
        2           k-2             Q12 = k-2
        3           k-1             Q13 = k-1           

3       0           k-1 0 2 3       Q20 = Q10 + Q12 + Q13   Q20+Q21+Q22+Q23     8   000,002,003;020,022;030,031,033
        1           k-2 1 3         Q21 = Q11 + Q13                                 k-1 + k-2 + k-1
        2           k-2 0 2         Q22 = Q10 + Q12
        3           k-1 0 1 3       Q23 = Q10 + Q11 + Q13   

4       0           k-1             Q30 = Q20 + Q22 + Q23   Q30+Q31+32+Q33      ?   (k-1 + k-2 + k-1) + (k-1 + (k-2)) + (k-1 + k-2 + k-1)
        1           k-2 1 3         Q31 = Q21 + Q23
        2           k-2 0 2         Q32 = Q20 + Q22
        k-1         k-1             Q33 = Q20 + Q21 + Q23   

        ......

L       

*/

找到一个通俗易懂的动态规划入门传送,大家可以学习一波。
点我传送

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喜鹊先生Richard

随缘~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值