2021-03-26-笔试-动态规划

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 列的第01234种状态有多少种取法。
当 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]:共 50 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;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_35632833/article/details/115247429
今日推荐