分析:
题目是一个有限制的数字序列问题。
题目的限制条件可以大体上分为:
- 给定数字的先后顺序限制
- 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前
- 最高位数字不为0
- 数字出现次数
- 数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次
本题中我们难以将数字的先后顺序和个数的限制同时简单实现.
我们只好分开实现。
我们优先实现顺序限制(条件更多方便具体化实现)
没有数字都出现至少一次的限制时,就可以有多具体情况(我们称这些数字为“前有趣数”):
- 只有2
- 只有2,0
- 只有2,3
- 只有2,0,3
- 只有2,0,1
- 有2,3,0,1
显然情况6就是我们要求的,不用数字出现限制去筛选。此时状态转移就可以很容易递推求各种情况的“前有趣数”设
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]为长度为就
i
i
i的
j
j
j号序列。
(我们接下来在序列中将"+"作为连接操作)
-
0号序列(情况1) 2...22 ⇐ 2...2 + 2 2...22\Leftarrow2...2+2 2...22⇐2...2+2,即 d p [ i ] [ 0 ] = d p [ i − 1 ] [ 0 ] \\dp[i][0] = dp[i-1][0] dp[i][0]=dp[i−1][0]
-
1号序列(情况2) 2..0..2 ⇐ 2..0.. + 2 或 2..0..0 ⇐ 2..0.. + 0 或 2...20 ⇐ 2...2 + 0 2..0..2\Leftarrow2..0..+2\\或2..0..0\Leftarrow2..0..+0\\或2...20\Leftarrow2...2+0 2..0..2⇐2..0..+2或2..0..0⇐2..0..+0或2...20⇐2...2+0,即 d p [ i ] [ 1 ] = ( d p [ i − 1 ] [ 1 ] ∗ 2 + d p [ i − 1 ] [ 0 ] ) \\dp[i][1] = (dp[i-1][1]*2+dp[i-1][0]) dp[i][1]=(dp[i−1][1]∗2+dp[i−1][0])
同理可以得到 -
d p [ i ] [ 2 ] = ( d p [ i − 1 ] [ 0 ] + d p [ i − 1 ] [ 2 ] ) dp[i][2] = (dp[i-1][0]+dp[i-1][2]) dp[i][2]=(dp[i−1][0]+dp[i−1][2])
-
d p [ i ] [ 3 ] = ( d p [ i − 1 ] [ 1 ] + d p [ i − 1 ] [ 3 ] ) + ( d p [ i − 1 ] [ 2 ] + d p [ i − 1 ] [ 3 ] ) dp[i][3] = (dp[i-1][1]+dp[i-1][3])+(dp[i-1][2]+dp[i-1][3]) dp[i][3]=(dp[i−1][1]+dp[i−1][3])+(dp[i−1][2]+dp[i−1][3])
-
d p [ i ] [ 4 ] = ( ( d p [ i − 1 ] [ 1 ] + d p [ i − 1 ] [ 4 ] ) + d p [ i − 1 ] [ 4 ] ) dp[i][4] = ((dp[i-1][1]+dp[i-1][4])+dp[i-1][4]) dp[i][4]=((dp[i−1][1]+dp[i−1][4])+dp[i−1][4])
-
d p [ i ] [ 5 ] = ( d p [ i − 1 ] [ 3 ] + d p [ i − 1 ] [ 5 ] ) + ( d p [ i − 1 ] [ 4 ] + d p [ i − 1 ] [ 5 ] ) dp[i][5] = (dp[i-1][3]+dp[i-1][5])+(dp[i-1][4]+dp[i-1][5]) dp[i][5]=(dp[i−1][3]+dp[i−1][5])+(dp[i−1][4]+dp[i−1][5])
#include<iostream>
#include<cstdio>
using namespace std;
const int Mod = 1000000007;
int dp[1005][6],N;
/*
0;仅有2
1:有2,0
2: 有2,3
3:有2,0,3
4:有2,0,1
5:有2,0,1,3
*/
int main(){
cin >> N;
for(int i = 0;i < 6;i++)dp[0][i] = 0;
dp[1][0] = 1;
for(int i = 2;i <= N;i++){
dp[i][0] = dp[i-1][0];
dp[i][1] = (dp[i-1][1]*2%Mod+dp[i-1][0])%Mod;
dp[i][2] = (dp[i-1][0]+dp[i-1][2])%Mod;
dp[i][3] = ((dp[i-1][1]+dp[i-1][3])%Mod+(dp[i-1][2]+dp[i-1][3])%Mod)%Mod;
dp[i][4] = ((dp[i-1][1]+dp[i-1][4])%Mod+dp[i-1][4])%Mod;
dp[i][5] = ((dp[i-1][3]+dp[i-1][5])%Mod+(dp[i-1][4]+dp[i-1][5])%Mod)%Mod;
}
cout << dp[N][5]<<endl;
return 0;
}