有趣的
##思考方向(dp)
由题意,因为0不能在首位,以及0,1,2,3的排列限制,得2只能在首位。
注:dp[i][j]为满足i状态j位数的数的个数
0.只有2 的情况dp[0][i] = 1;
1.只有0,2 的情况 dp[1][i] = dp[0][i-1] + 2dp[1][i-1];
2.只有2,3的情况 dp[2][i] = dp[0][i-1] + dp[2][i-1];
3.只有0,2,3的情况dp[3][i] = dp[1][i-1] + dp[2][i-1]+2dp[3][i-1];
4.只有0,1,2的情况 dp[4][i] = dp[1][i-1]+2dp[4][i-1];
5. 0,1,2,3 的情况dp[5][i] = dp[3][i-1] + dp[4][i-1] + 2dp[5][i-1];
正确代码
(一开始以为只需要最后的时候将结果%1000000007,结果每一个状态转移方程都要,离散数学里证明过这样是等价的但是忘了,先这样记住这个技巧)
#include <iostream>
#define N 1001
using namespace std;
long long dp[6][N] = {0};
int main()
{
// cout << "Hello world!" << endl;
int n;
cin>>n;
dp[0][0] = 1;
for(int i = 1 ;i < n;i++)
{
dp[0][i] = 1;
dp[1][i] = (dp[0][i-1] + 2*dp[1][i-1])%1000000007;
dp[2][i] = (dp[0][i-1] + dp[2][i-1])%1000000007;
dp[3][i] = (dp[1][i-1] + dp[2][i-1]+2*dp[3][i-1])%1000000007;
dp[4][i] = (dp[1][i-1]+2*dp[4][i-1])%1000000007;
dp[5][i] = (dp[3][i-1] + dp[4][i-1] + 2*dp[5][i-1])%1000000007;
}
cout<<dp[5][n-1]%1000000007;
return 0;
}