当前位置: 代码迷 >> 综合 >> 蓝桥杯-Algo-3 K好数 (DP动态规划)
  详细解决方案

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

热度:67   发布时间:2023-11-14 13:59:35.0

问题描述

如果一个自然数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<iostream>
#include<cstring>
#include<cmath>
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<m;i++)dp[1][i] = 1;dp[1][0] = 0;for(i=2; i<=n; i++)// 长度为i的数{for(j=0; j<m; j++)//以j结尾{for(k=0; k<m; k++){if(fabs(j-k)!=1)dp[i][j] = (dp[i-1][k]%Mod+dp[i][j]%Mod)%Mod;//状态转移方程!!!}//cout<<dp[i][j]<<endl;}}for(j=0; j<m; j++)sum = (sum%Mod + dp[n][j]%Mod)%Mod;cout<<sum<<endl;}return 0;
}

 

 

  相关解决方案