版权声明:希望能在自己成长的道路上帮到更多的人,欢迎各位评论交流 https://blog.csdn.net/yiqzq/article/details/82353983
原题地址: http://118.190.20.162/view.page?gpid=T2
思路:考虑dp,状态转移及定义详见代码
#include <bits/stdc++.h>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)+1
#define CLR(x,y) memset((x),y,sizeof(x))
#define fuck(x) cerr << #x << "=" << x << endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int seed = 131;
const int maxn = 1e5 + 5;
const int mod = 1e9 + 7;
/*
一. 2
二. 2 0
三. 2 3
四. 2 0 1
五. 2 3 0
六. 2 3 0 1
定义6种dp状态
*/
ll dp[1005][10];//dp[i][j]表示长度为i,状态为j的种类数
int main() {
int n;
scanf("%d", &n);
dp[1][1] = 1;
for (int i = 2; i <= n; i++) {
dp[i][1] = 1;
dp[i][2] = dp[i - 1][1] + 2 * dp[i - 1][2];
dp[i][3] = dp[i - 1][1] + dp[i - 1][3];
dp[i][4] = dp[i - 1][2] + 2 * dp[i - 1][4];
dp[i][5] = dp[i - 1][2] + dp[i - 1][3] + 2 * dp[i - 1][5];
dp[i][6] = dp[i - 1][4] + dp[i - 1][5] + 2 * dp[i - 1][6];
/*
以下的状态转移均由长度为i-1得来
1.以状态1结尾的只有一种,那就全部是2
2.以状态2结尾的可以由状态1末尾加一个0得来,或者状态2末尾加一个0或1(这是乘以2倍的原因)
3.以状态3结尾的可以由状态1末尾加一个3得来,或者由状态3末尾加一个3得来
4.以状态4结尾的可以由状态2末尾加一个1得来,或者状态4末尾加一个0或3得来(2倍)
5.以状态5结尾的可以由状态2末尾加一个3得来,由状态3末尾加一个0得来,或者状态5结尾加一个0或3
6.以状态6结尾的可以由状态4末尾加一个3得来,由状态5末尾加一个1得来,或者状态5结尾加一个0或3
*/
for (int k = 1; k <= 6; k++) dp[i][k] %= mod;
}
printf("%lld\n", dp[n][6]);
return 0;
}