藍橋杯 K好數 (dp)------------C語言
阿新 • • 發佈:2019-01-27
/*問題描述
如果一個自然數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;
}