1. 描述
牛牛有一个3*n的土地。这个土地有3行,n列。牛牛想在土地上种至少一朵花。为了花儿能够茁壮成长,每一朵花的上下左右四个方向不能有其他的花。问有多少种种花的方案。为防止答案过大,答案对1e9+7取模。
2. 分析
土地总共3行,那么就有 2 的 3 次方, 8种种树的方式:
000
001
010
100
011
101
110
111
要求上下左右不能有树,所以:
011
110
111
这三种不满足要求。
还剩下:
000
001
010
100
101
这五种状态。
又因为,当 n = 1 时,要求土地上种至少一朵花,所以 000,也不满足要求。但当 n=2 的时候,前一列是可以取000这种状态的,只要 n=2 这一列不取 000 这种状态就好了。因此,每一列其实都有5种状态。最后把得到的总状态数-1即可。
dp[0][i],dp[1][i],dp[2][i],dp[3][i],dp[4][i] 分别代表第 i 列的第0,1,2,3,4种状态有多少种取法。
当 n = 1时,dp[0][0] = 1,dp[1][0] = 1, dp[2][0] = 1,dp[3][0] = 1,dp[4][0] = 1
共有 5 种取法 (最后还需要减去1)
当 n = 2 时,
此时dp[0][1]:共 5 种
0 0
0 0
0 0
0 1
0 0
0 0
0 0
0 1
0 0
0 0
0 0
0 1
0 1
0 0
0 1
此时dp[1][1]:共 3 种,有两种不行,如下
1 0
0 0
0 0
//1 1
//0 0
//0 0
1 0
0 1
0 0
1 0
0 0
0 1
//1 1
//0 0
//0 1
所有的都依次类推
3. 代码
class Solution {
public:
int solve(int n) {
int MOD = 1e9+7;
vector<vector<long> > dp(5, vector<long>(n,0));
for(int i = 0; i < 5; i++){
dp[i][0] = 1;
}
for(int i = 1; i < n; i++){
dp[0][i] = (dp[0][i - 1] + dp[1][i - 1] + dp[2][i - 1] + dp[3][i - 1] + dp[4][i - 1]) % MOD; // 000
dp[1][i] = (dp[0][i - 1] + dp[2][i - 1] + dp[3][i - 1]) % MOD; // 001
dp[2][i] = (dp[0][i - 1] + dp[1][i - 1] + dp[3][i - 1] + dp[4][i - 1]) % MOD; // 010
dp[3][i] = (dp[0][i - 1] + dp[1][i - 1] + dp[2][i - 1]) % MOD; // 100
dp[4][i] = (dp[0][i - 1] + dp[2][i - 1]) % MOD; // 101
}
return (dp[0][n - 1] + dp[1][n - 1] + dp[2][n - 1] + dp[3][n - 1] + dp[4][n - 1] - 1) % MOD;
}
};