平衡的选择题

最优解

考虑动态规划,用表示前题的选项A和C的差距为,B和D的差距为.那么的范围为[-1,1],的范围为[-2,2]。因为负数不好动态规划,所以把j-1作为A和C的差距,这样的范围就是[0,2]。同理让k-2作为B和D的差距,的范围就变成了[0,4]。然后枚举第题的答案来进行转移。
当然可以写15个If去进行转移,但是也可以利用二进制位表示每个选项选与不选来转移,减少代码量和思维量。
因为的答案只取决于的答案,所以第一维可以利用滚动数组优化掉,空间复杂度
时间复杂度

int solve(int n){
    int mod = 1e9 + 7;
    int dp[2][3][5];
    memset(dp, 0, sizeof dp);
    int cur = 0, nxt = 1;
    for(int mask = 1; mask < 16; ++mask){
        int A = mask&1, B = (mask>>1)&1, C = (mask>>2)&1, D = (mask>>3)&1;
        dp[cur][1+A-C][2+B-D]++;
    }
    for(int i = 1; i < n; ++i){
        memset(dp[nxt], 0, sizeof dp[nxt]);
        for(int j = 0; j < 3; ++j){
            for(int k = 0; k < 5; ++k){
                for(int mask = 1; mask < 16; ++mask){
                    int A = mask&1, B = (mask>>1)&1, C = (mask>>2)&1, D = (mask>>3)&1;
                    if(j+A-C < 3 && j+A-C >= 0 && k+B-D < 5 && k+B-D >= 0)
                        dp[nxt][j+A-C][k+B-D] =(dp[nxt][j+A-C][k+B-D] + dp[cur][j][k])%mod;
                }
            }
        }
        swap(nxt, cur);
    }
    int ans = 0;
    for(int i = 0; i < 3; ++i) for(int j = 0; j < 5; ++j) ans = (ans + dp[cur][i][j])%mod;
    return ans;
}
全部评论

相关推荐

Hello_WordN:咱就是说,除了生命其他都是小事,希望面试官平安,希望各位平时也多注意安全
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务