题目描述:
如果一个自然数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
解析:
满足任意相邻两位都不是相邻的数字叫做K好数,即相邻两位数字差值的绝对值不等于1,每一位存在取0 ~ K - 1的任何一个值的可能性(最高位不能取0),因此考虑枚举每一位取0 ~ K - 1的情况。建立如下的二维vector记录第 i 位以 j 结尾情况下的K好数的个数:
vector<vecotr<int> > v(L, vector<int> (K, 0)); // 第一维表示第几位, 第二维表示该位的数字
以第一位表示最高位,不能取0,因此初始条件为:
for (int j = 1; j < K; ++j) {
v[0][j] = 1;
}
依次往后枚举第 i 位取 j 的情况,同时枚举前一位的取值的情况,构成递推关系:
for (int i = 1; i < L; ++i) {
for (int j = 0; j < K; ++j) {
for (int k = 0; k < K; ++k) {
if (abs(k - j) != 1) { //前一位为k,后一位为j,不相邻则加上上一位的个数
v[i][j] += v[i - 1][k];
v[i][j] %= MOD;
}
}
}
}
示意图:
代码实现:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const int MOD = 1000000007;
int main() {
int K, L;
cin >> K >> L;
vector<vector<int> > v(L, vector<int> (K, 0));
if (K == 1)
cout << 0;
else {
for (int j = 1; j < K; ++j) {
v[0][j] = 1;
}
for (int i = 1; i < L; ++i) {
for (int j = 0; j < K; ++j) {
for (int k = 0; k < K; ++k) {
if (abs(k - j) != 1) {
v[i][j] += v[i - 1][k];
v[i][j] %= MOD;
}
}
}
}
int ans = 0;
for (int j = 0; j < K; ++j) {
ans += v[L - 1][j];
ans %= MOD;
}
cout << ans;
}
return 0;
}