DP-蓝桥杯-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。


刚读到题时,第一反应就是用DFS写,因为前面刚学了DFS,写完后发现题目要求的数据量十分庞大,显然DFS的时间会过长,后来才去找结构特征

先贴DFS写的

import java.util.Scanner;
//K好数(DFS 数据量太大时,运行时间太长!)
	public static int L;
	public static int K;
	public static int count;
	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		K = cin.nextInt();
		L = cin.nextInt();
		int a[]=new int[L];
		find(a,0);
		System.out.println(count);
		cin.close();
	}
	
	public static void find(int a[],int i){
		if(i==L){
			count++;
			if(count>=1000000007)
			{
				count-=1000000007;
			}
			return;
		}
		for(int j=0;j

只能满足题目中数据规模30%,后来发现,对于给定K进制,若位数为L-1的K好数已知,则位只需在最后一位添加满足第L-1位和L位相差不为1,便成了L位K好数。所以要用到动态规划。可惜我并没有根据这一规律构造出结构特征式,后来提交一次看了锦囊2才恍然大悟。

用F[i][j]表示长为i,最后一位数字是j的K好数的个数,则F[i][j]=\sum F[i-1][k],其中|j-k|!=1。

用F[i][j]表示长为i,最后一位数字是j的K好数的个数,则F[i][j]=\sum F[i-1][k],其中|j-k|!=1。

代码如下:

import java.util.Scanner;
//K好数(DP)
public class DP_Kgood {
	public static int l;
	public static int k;
	public static int count;
	public static int[][] a;
	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		k = cin.nextInt();
		l = cin.nextInt();
		a=new int[l+1][k+1];
		//对数组赋初值
		a[1][0]=0;
		for(int j=1;j=1000000007)
				count-=1000000007;
		}
		System.out.println(count);
		
	}
	//从二位数开始,循环求出更高位数的值
	public static void put(int n,int k){
		for(int l=1;l<=n;l++){
			for(int j=0;j=1000000007)
							a[l][j]-=1000000007;
					}
				}
			}
		}
	}
}

你可能感兴趣的:(算法)