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

来源:互联网 发布:申请软件著作权材料 编辑:程序博客网 时间:2024/05/23 19:11

 算法训练 K好数  
时间限制:1.0s   内存限制:256.0MB
      
锦囊1
使用动态规划。
锦囊2
用F[i][j]表示长为i,最后一位数字是j的K好数的个数,则F[i][j]=\sum F[i-1][k],其中|j-k|!=1。
问题描述

如果一个自然数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。



这道题目我也有点懵,对于dp(动态规划)算法,也是了解一些:https://www.cnblogs.com/wust-owen/archive/2016/04/11/5377126.html    http://blog.csdn.net/cangchen/article/details/45044811



看了一下,思路应该是这样子的:当前行 等于 除了相邻数外 的数值 进行累加(但不知道为什么三位数的K进制等于两位数的K进制累加)

dp[i][j],其中i代表数字有几位(数位),j代表首位放j

dp[0][0]=1,dp[0][1]=1,dp[0][2]=1,dp[0][3]=1


dp[2][0]=dp[1][0]+dp[1][2]+dp[1][3]=3

dp[2][1]=dp[1][1]+dp[1][3]=2

dp[2][2]=dp[1][0]+dp[1][2]=2

dp[2][3]=dp[1][0]+dp[1][1]+dp[1][3]=3


dp[3][0]=dp[2][0]+dp[2][2]+dp[2][3]=8

dp[3][1]=dp[2][1]+dp[2][3]=5

dp[3][2]=dp[2][0]+dp[2][2]=5

dp[3][3]=dp[2][0]+dp[2][1]+dp[2][2]=8


……………………


结果:

行代表位数,列代表k进制

 0123111112322338558421131321



自己的理解:

※※※关键来了:可以这样想的,两位的4进制已经不相邻了。如果是3位数,则第3位数与第2位数应该也不相邻,两两不相邻,则肯定不相邻。3位的4进制 就是 在2位的4进制的基础上 进行添加第3位数值)


(下面就是演示上面那句话,红色代表的是第三位数)

一、如果是2位的4进制:则是00 02 03,11 13,20 22,30 31 33

二、如果是3位的4进制:

以第二位为0的三位数:000 200 300,002 202 302,003 203 303,(6个)

以第二位为1的三位数:111 311,113 313,(4个)

以第二位为2的三位数:020 220,022 222,(2个)

以第二位为3的三位数:030 130 330,031 131 331,032 132 332,(6个)

(最后除了0开头的就剩下18个,符合题意,因为0开头都不是有意义的数,0XX)



代码如下:

import java.util.Scanner;public class Main {static int MOD = 1000000007;public static void main(String[] args) {// TODO Auto-generated method stubScanner scanner = new Scanner(System.in);int k = scanner.nextInt();int l = scanner.nextInt();int[][] dp = new int[101][101];for(int i=0;i<k;i++){dp[1][i]=1; //第1行初始化为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){//左右不相邻dp[i][j]=dp[i][j]+dp[i-1][j2];//循环累加上一行idp[i][j]%=MOD;}}}}int sum = 0;for(int i=1;i<k;i++){//将最后一行累加,第一列不统计sum+=dp[l][i];sum%=MOD;}System.out.println(sum);}}


转载地址:http://blog.csdn.net/jopus/article/details/20315381       http://blog.csdn.net/libin56842/article/details/19910663

原创粉丝点击