1. 程式人生 > >藍橋杯 K好數 (dp)------------C語言

藍橋杯 K好數 (dp)------------C語言

/*問題描述
如果一個自然數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。
思路:用動態規劃;若求 K=4 進位制 L=1 位則 有 0,1,2,3 。共4種,當L>=2時 第一位不能為0
所以 計算第一位時 把 a[1][0]=0;就是說可以 20 不可 02 可以 200,300
a[i][j]表示 以 j(0,1,2,3.。.。K-1)數 為第i位上的數字 儲存的是 這種情況下的K好數
\j 0 1 2 3.。。。K-1
i
1 0 1 1 1.。。。 1
2 2 2 1 2.。。。
3 5 4 3 6.。。。



L
*/

#include <stdio.h>
int abs(int a)
{if(a>=0)return a;
  else return -a;
}
int main()
{long int k,l,m,i,j;
long int sum=0;
long int a[105][105]={0}; 
scanf("%ld%ld",&k,&l);
if(l>=2)
{  for(i=0;i<k;i++)// 當L==1時 所有進位制內的數都可以 所以每個數都是 1個K好數 
    a[1][i]=1;
    a[1][0]=0;//第一位不能為0 

    for(i=2
;i<=l;i++) for(j=0;j<k;j++) for(m=0;m<k;m++) {if(abs(j-m)!=1) a[i][j]+=a[i-1][m];//a[i][j]表示第i位填 j 數字a[i-1][m]表示j可與高位那些 m 數結合 if(a[i][j]>1000000007)a[i][j]%=1000000007;//a[i-1][m]表示 以 m 數做低位時的 K好數數目 } //a[i][j]表示 以 j 數做低位時的 K好數數目 } for(i=0;i<k;i++) {sum
+=a[l][i]; if(sum>1000000007)sum%=1000000007; } printf("%ld\n",sum); return 0; }