算法训练 K好数 时间限制:1.0s 内存限制:256.0MB 问题描述
如果一个自然数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。
问题分析:
使用动态规划。
参考文献:键盘上的舞者的博客:http://blog.csdn.net/libin56842/article/details/19910663
dp[i][j],其中 i 表示总共有多少位(i<=L),j 表示最后面那个数字(j<K)
我们是这样动态规划的:
总共1位: 全部初始化为1,方便dp[2][j] 规划。
总共2位:…… (还是直接看下面的数组吧)。
当输入:>> 4 2 时,如下:(行i<L,列:表示K进制(4进制{0,1,2,3}))
0 | 1 | 2 | 3 | |
1 | 1 | 1 | 1 | 1 |
2 | 3 | 2 | 2 | 3 |
所以:7 = 2 + 2 + 3
ps:我们每次往后面加一个数字(列 表示所追加的数字,行表示现在有多少位)
附录:
/*
Name: 蓝桥杯:K好数
Copyright: Analyst
Author: Analyst
Date: 02/03/14 22:07
Description: dev-cpp 5.5.3
*/
#include <stdio.h>
int main()
{
int K,L,i,j,x;
long long sum = 0,dp[500][105];
scanf("%d%d",&K,&L);
for (j = 0; j < K; ++j) //第1行初始化为1,便于下面for循环i=2时的计算
dp[1][j] = 1;
for (i = 2; i <= L; ++i)
for (j = 0; j < K; ++j)
for (x = 0; x < K; ++x)
if (x != j-1 && x!= j+1) //左右不相邻
{
dp[i][j] += dp[i-1][x]; //循环累加上一行for(..x..)
dp[i][j] %= 1000000007;
}
for (j = 1; j < K; ++j) //将最后一行累加,第一列0,不统计
{
sum += dp[L][j];
sum %= 1000000007;
}
printf("%lld\n",sum);
return 0;
}
提交序号 | 姓名 | 试题名称 | 提交时间 | 代码长度 | 语言 C C++ JAVA | 评测结果 正确 错误 编译出错 运行错误 运行超时 内存超限 | 得分 100 1~99 0 | CPU使用 | 内存使用 | 评测详情 |
---|---|---|---|---|---|---|---|---|---|---|
106844 | Analyst | K好数 | 03-02 22:41 | 567B | C | 正确 | 100 | 15ms | 1.160MB | 评测详情 |
转载请保留原文地址:http://blog.csdn.net/jopus/article/details/20315381