date7.24 K好数
作者:互联网
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
思路
什么是K好数
先要理解题目中的K好数是什么意思,简单来说相邻两位上的值不是前后相邻关系,例如第一位上数为1时第二位不能为0和2。题目中是L位K进制,所以每一位上的取值范围都为[0,K-1],且数的位数为L位。
取模运算
注意题中输出对那个数取模后的值,要明白取模运算只有对象是整数间时才等于取余运算,取模和取余是有区别的,但当对象是整数间时两者相同。具体理解可以参考:https://baike.baidu.com/item/取模运算/10739384
动态规划
什么是动态规划?动态规划是通过拆分问题,使得问题能够递推的方式去解决,当前子问题的解可以有上一级子问题的解推出。简单来说现在所求问题的解可以通过上一次问题的解推出。
这题样例输出是2位4进制,以这个样例来分析一下思路。
这里行表示的是位数,列表示的是进制,这题是4进制所以取值范围是[0,3],格子中的数值位当第一位为该数时K好数的情况有几个。位数不可能为0所以0的那行为空,当位数为1时我们能很清楚知道,第一位为范围内的数都有1种情况,所以表格中一位数的那行每个数在第一位的时候的情况都为1,但注意进制第一位不能为0,所以可以写出,但不做计算。
这里推一下二位数的时候第一位为0的情况,现在就是选择第二位的数不与0相邻下的情况,第二位可以为0,2,3,而它们的情况数都为所1,以两位数第一位为0的时候有3种情况。当第一位为1时,第二位可以为1,3,这是看上一级1和 3的情况都分别为1所以情况数为2。
当数为三位四进制时,这个时候就要用的到二位四进制时的解来求,第一位为1的时候,不相邻的数有1,3,在二位四进制时情况数分别为2和3所以此时情况数为5。
推想到L位数时,因为我们确定了第一位数,第二位数不与第一位数相邻即可,所以使用上一级L-1位数第一位数与L位第一位数不相邻情况相加便是这次结果的解。即arry[i][j] += arry[i-1][m],i为位数,j为第一位数的值,m为不与j相邻的数。
代码
package daily;
import java.util.Scanner;
public class d7_14 {
final static int mode = 1000000007;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int K = sc.nextInt();//输入K进制
int L = sc.nextInt();//输入L位
int sum = 0;
int [][] arry = new int[L + 1][K];//横坐标是位数,纵坐标是进制
for(int i = 1;i <= L;i++){
for(int j = 0;j < K;j++)
arry[i][j]=0;//先进行初始化
}
for (int i = 0;i < K;i++){//1位K进制时每位上K好数个数都为1
arry[1][i]=1;
}
for (int i = 2;i <= L;i++){
for(int j = 0;j < K;j++){
for(int m = 0;m < K;m++){
if(m != j - 1 && m != j+1){//判断前后位上数值是否相邻
arry[i][j] += arry[i-1][m];
arry[i][j] %= mode;
}
}
}
}
for(int j = 1;j < K;j++){
sum += arry[L][j];
sum %= mode;
}
System.out.println(sum);
}
}
标签:取模,第一位,好数,int,date7.24,位数,进制 来源: https://www.cnblogs.com/jing-study/p/15057173.html