试题编号: | 201312-4 |
试题名称: | 有趣的数 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 我们把一个数称为有趣的,当且仅当: 输入格式 输入只有一行,包括恰好一个正整数n (4 ≤ n ≤ 1000)。 输出格式 输出只有一行,包括恰好n 位的整数中有趣的数的个数除以1000000007的余数。 样例输入 4 样例输出 3 |
思路:不考虑条件1,共有六种合法状态:
1、只含2
2、只含2、0
3、只含2、3
4、只含2、0、1
5、只含2、0、3
6、含4种数字。
用dp[i][0]~dp[i][5]来分别表示长度为i的整数,满足上述状态的个数。
那么可以得到状态转移方程:
1、dp[i][0]=1,位数为i且只含2的整数有且只有1个
2、dp[i][1]=2*dp[i-1][1]+dp[i-1][0],位数为i且只含2、0的整数可以由位数为i-1的只含2、0的整数通过在末尾添加0或者2得到,也可以由位数为i-1的只含2的整数在末尾添加0得到。
其余的状态转移方程以此类推。
参考网上。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-6;
const int INF=0x3f3f3f3f;
const int MOD=1e9+7;
const int N = 1e3+5;
int dp[N][6];
void solve(int n) {
dp[1][0]=1;
for(int i=2; i<=n; i++) {
dp[i][0]=1;///只含2
dp[i][1]=(2*dp[i-1][1]%MOD+dp[i-1][0])%MOD;///只含2和0,末尾分别是0或2;末尾为2
dp[i][2]=(dp[i-1][2]+dp[i-1][0])%MOD;///只含2,3;末尾为2或3
dp[i][3]=(2*dp[i-1][3]%MOD+dp[i-1][1])%MOD;///只含2,0,1;末尾为2或1;末尾1
dp[i][4]=((2*dp[i-1][4]%MOD+dp[i-1][2])%MOD+dp[i-1][1])%MOD;///只含2,0,3;末尾1或3,末尾0或3
dp[i][5]=((2*dp[i-1][5]%MOD+dp[i-1][4])%MOD+dp[i-1][3])%MOD;///含4个数字 末尾1或3())
}
}
int main() {
int n;
scanf("%d",&n);
solve(n);
printf("%d\n",dp[n][5]);
return 0;
}