蓝桥杯-Algo-3 K好数 (DP动态规划)

问题描述

如果一个自然数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好数的定义自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数。从测试样例我们可以看出,K好数就是L位的K进制数中任意相邻的两位不是相邻数字的数。比如 K=2,L=2时,两位二进制数有 00 01 10 11,其中只有11符合条件(此题中0不算作K好数)。

解题思路:由题易得,如果我们要求n位的K好数,只需要在n-1位K好数的基础上增加一位与n-1位K好数的最后一位不相邻的数字就是n位的K好数。也就是说我们当前的状态需要用到前一阶段的状态,所以本题可以用动态规划求解。我们可以用DP[i][j]表示长为i,最后一位数字是j的K好数的个数,把DP[N][I]加起来即可得结果。

 

为了理清状态之间的转移有关系,我们可以假设当前要求出 DP[3][0](以0结尾的K进制三位K好数的个数),则需要知道所有两位且结尾数字不与0相邻的的K好数。(在它们的结尾加上一个0就能得到3位以0结尾的K好数),即DP[3][0] = DP[2][0]+DP[2][2]+DP[2][3]+……+DP[2][K-1]。

 

把上述文字抽象成状态转移方程

状态转移方程:DP[i][j] = (Sum[dp[i-1][k]).(其中|J-K|!=1);

#include
#include
#include
using namespace std;
const int Mod = 1000000007;
int dp[105][200];
//用F[i][j]表示长为i,最后一位数字是j的K好数的个数,则F[i][j]=\sum F[i-1][k],其中|j-k|!=1。
int main(void)
{
    int k,n,i,j,m;

    while(cin>>m>>n)
    {
        int sum = 0;
        memset(dp,0,sizeof dp);
        
        for(i=0;i

 

 

你可能感兴趣的:(数据结构与算法)