藍橋杯---K好數

                                                      算法訓練 K好數  

                                         時間限制:1.0s   內存限制:256.0MB

錦囊1

錦囊2

錦囊3

問題描述

如果一個自然數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。

 

問題分析

        問題的大意是,L位數的K進製表示中相鄰的兩位都不是相鄰的數字。 比如:L=2,K=4,  4進製表示的數字只能是0--3,則2位數的二進制,共有下面幾種可能:

10 ,11 ,12,13,20,21,22,23,30,31,32,33(注最高位不能爲0)。 由於相鄰的兩位都不是相鄰的數字,所以K好數爲11,13,20,22,30,31,33共7個。

 

解決方法 :  (動態規劃)

        這裏首先對動態規化做簡單描述,具體可以自己查找視頻。

       動態規劃(Dynamic Programming)就是將求解的子問題分解爲若干個子問題,按順序求解子問題,前一個子問題的解爲後一子問題的求解提供了有用的信息。狀態轉移 方程是動態規劃的關鍵。

        本題的解題思想:因爲有L位數,從最低位開始依次作爲子問題。比如:L=2,K=4    

 

 代碼實現:

#include<iostream>
#include<cstring>
using namespace std;

const int MAX = 101;
const int M = 1000000007; 

int f[MAX][MAX];
int main()
{
	int l, k;
	while(cin>>k>>l)
	{
		//特殊處理 
		if(l == 1)
		{
			cout<<k-1<<endl; 
		}
		else
		{
			memset(dp, 0, sizeof(dp));
			//初始化 
			for(int i=0; i<k; i++)
			{
				f[1][i] = 1;
			}
			 
			for(int i=2; i<l; i++)//第2位到l-1位 
			{
				for(int j=0; j<k; j++)//可能取值0-k-1 
				{
					int cnt = 0;
					for(int r=0; r<k; r++)
					{
						if(r == j-1 || r == j+1) //相鄰爲不能相同 
						{
							continue;
						}
						cnt = (cnt + f[i-1][r])%M;
					}
					f[i][j] = cnt;
				}
			}
			
			int sum = 0;
			//對最高位進行處理 
			for(int j=1; j<k; j++) 
			{
				int cnt=0;
				for(int r=0; r<k; r++)
				{
					if(r == j-1 || r == j+1)
					{
						continue;
					}
					cnt = (cnt + f[l-1][r])%M;
				}
				sum = (sum+cnt)%M;
			}
		    cout<<sum<<endl; 
		}
	}	
	
	return 0;
 } 

 

 

 

 

 

 

 

 

 

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