藍橋杯 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.00 281ms 21.08MB 輸入 輸出
2 正確 10.00 296ms 21.15MB VIP特權
3 正確 10.00 140ms 20.97MB VIP特權
4 正確 10.00 156ms 21.12MB VIP特權
5 正確 10.00 218ms 21.22MB VIP特權
6 正確 10.00 234ms 21.21MB VIP特權
7 正確 10.00 250ms 21.21MB VIP特權
8 正確 10.00 265ms 21.26MB VIP特權
9 正確 10.00 250ms 21.34MB VIP特權
10 正確 10.00 265ms 21.34MB VIP特權

 

感受:

1.作爲第一道用JavaAC的動態規劃題,感覺還是不錯的。以前總是感覺java和c++比要慢的多,很多題用c++實現都過了,但用java實現就是超時,抓狂,,,  但是現在ac了之後感覺其實java更鍛鍊自己的能力,讓自己更加懂得優化自己的代碼。

2.還有就是以後寫動態規劃題的時候注意理思路,套框架,從根本上理解並掌握動態規劃的精髓。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章