题意不说了,中文的题意!= =!
思路:
DP思想!
可以这么想,设计一个二维的dp[i][j],i表示当前填第i个数,此时为第j 个状态!
第一维不用说,说说第二维!
总共有四个数0,1,2,3,那么当前该填i个数时,此时已经填了一些数,还剩下没填的数,这个填了的数的集合就是状态!
0,1,2,3的四个数总共子集有0,1,2,3,01,02,03,12,13,23,012,013,023,123,0123,想一想可以知道,符合要求的状态只有六个!
分别是:
2,02,23,012,023,0123
所以第二维只需要6个数即可!
拿一个状态举例子吧:
比如说这个状态是023,那么转移可以由02 加个3 转来,也可以有23 加个0转来,也可以有023 加0 或者3 转来!
因此[4] = [1] * 1 + [2] * 1 + [4] * 2;
注意取模即可!
坑:
虽然取模了,仍然会爆int
开long long 就好了!
详细见代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mod = 1000000007;
const int maxn = 1000 + 10;
typedef long long ll;
ll dp[maxn][7];
int main(){
int n;
scanf("%d",&n);
for (int i = 1; i <= n; ++i){
dp[i][0] = 1;
dp[i][1] = (dp[i-1][0] % mod + (dp[i-1][1]%mod) * 2) % mod;
dp[i][2] = (dp[i-1][0] % mod + dp[i-1][2] % mod) % mod;
dp[i][3] = (dp[i-1][1] % mod + (dp[i-1][3] % mod) * 2) % mod;
dp[i][4] = (dp[i-1][1]%mod + dp[i-1][2]%mod + (dp[i-1][4]%mod) * 2) % mod;
dp[i][5] = (dp[i-1][3] % mod + dp[i-1][4] % mod + (dp[i-1][5] % mod) * 2) % mod;
}
printf("%lld\n",dp[n][5] % mod);
return 0;
}
试题编号: | 201312-4 |
试题名称: | 有趣的数 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: |
问题描述
我们把一个数称为有趣的,当且仅当:
1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次。 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前。 3. 最高位数字不为0。 因此,符合我们定义的最小的有趣的数是2013。除此以外,4位的有趣的数还有两个:2031和2301。 请计算恰好有n位的有趣的数的个数。由于答案可能非常大,只需要输出答案除以1000000007的余数。
输入格式
输入只有一行,包括恰好一个正整数n (4 ≤ n ≤ 1000)。
输出格式
输出只有一行,包括恰好n 位的整数中有趣的数的个数除以1000000007的余数。
样例输入
4
样例输出
3
|