##思考方向(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; }