蓝桥杯 k好数-java实现 动态规划

问题描述

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

题解:

首先解释一下,

动态规划:将待求的问题分解成若干子问题,先求解子问题然后从这些子问题中获得原问题的解。
            与分治法的区别:动态规划分解的子问题可能不是相互独立的。
            基本要素:1.最优子结构,2,重叠子问题
            最优子结构:当问题的最优解包含了其子问题的最优解的时候,称其具有最优子结构
            重叠子问题:每次产生的子问题并不都是新的问题,有些子问题被重复计算多次
            自下往上:
            备忘录算法:(自顶向下)
            状态压缩:
            步骤:1.划分阶段 2.正确选择状态变量 3.确定决策变量以及允许决策的集合
            4.确定状态转移方程 5.确定阶段指标函数和最优指标函数,建立动态规划基本方程

一般情况下,只要能做到备忘录算法这一步,基本就ac了。

其次,说一下这道题,首先划分阶段,L位数从 最低位到最高位分为不同的阶段,状态变量就是位置i了,表示在第几位,

决策变量就是的d[i][j]了即表示将i位置的值置为j时的k好数的个数,状态转移方程:由分析,其状态转移方程从最低+1位开始,

d[i][j]= ∑d[i-1][r](r!=j+1&&r!=j-1&&0<=r<=k-1) 最高位j!=0,需特殊处理;其初始条件为d[0][j]=1;不受约束。

于是乎代码如下:



import java.util.Scanner;
//k好数 dp
public class Main {
	
	final static int maxn=100;
	final static int M=1000000007;
	static int d[][]=new int[maxn+5][maxn+5];//d[i][j]表示将i位置的值置为j时的k好数的个数
	
    //由分析,其状态转移方程从最低+1位开始,d[i][j]= ∑d[i-1][r](r!=j+1&&r!=j-1&&0<=r<=k-1)            
//最高位j!=0,需特殊处理
	//其初始条件为d[0][j]=1;不受约束
	public static void main(String[] args) {
		Scanner cin= new Scanner(System.in);
		int k,l;
		k=cin.nextInt();
		l=cin.nextInt();

		for(int j=0;j<k;j++) d[0][j]=1;
		for(int i=1;i<l;i++)//i=0已经初始化过了
		{
			for(int j=0;j<k;j++)//求第i个位置放置每一个值时d[i][j]的大小;
			{
				d[i][j]=0;
				for(int r=0;r<k;r++)
				{
					if(r!=j+1&&r!=j-1)//状态转移表达式要满足的条件
					{
						d[i][j]+=d[i-1][r];
						d[i][j]%=M;
					}
				}
			}
		}
		int ans=0;
		for(int	j=1;j<k;j++)//最后一位的情况不包括0
		{
			ans+=d[l-1][j];
			ans%=M;
		}
		System.out.println(ans);
	}

}

测试样例:

详细记录
评测点序号评测结果得分CPU使用内存使用下载评测数据
1正确10.00281ms21.08MB输入 输出
2正确10.00296ms21.15MBVIP特权
3正确10.00140ms20.97MBVIP特权
4正确10.00156ms21.12MBVIP特权
5正确10.00218ms21.22MBVIP特权
6正确10.00234ms21.21MBVIP特权
7正确10.00250ms21.21MBVIP特权
8正确10.00265ms21.26MBVIP特权
9正确10.00250ms21.34MBVIP特权
10正确10.00265ms21.34MBVIP特权

 

感受:

1.作为第一道用JavaAC的动态规划题,感觉还是不错的。以前总是感觉java和c++比要慢的多,很多题用c++实现都过了,但用java实现就是超时,抓狂,,,  但是现在ac了之后感觉其实java更锻炼自己的能力,让自己更加懂得优化自己的代码。

2.还有就是以后写动态规划题的时候注意理思路,套框架,从根本上理解并掌握动态规划的精髓。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值