洛谷P2327 [SCOI2005]扫雷
? 解题记录 ? ? 洛谷 ? ? 动态规划 ? ? 状态压缩 ?    2017-10-30 23:13:31    371    0    0

题目描述

输入输出格式

输入格式:

 

第一行为N,第二行有N个数,依次为第二列的格子中的数。(1<= N <= 10000)

 

输出格式:

 

一个数,即第一列中雷的摆放方案数。

 

输入输出样例

输入样例#1: 复制
2
1  1
输出样例#1: 复制
2​​

 

一道很小型的状压,我们用一个二位二进制记录到当前行的时候,当前行的下一格和当前行对应的格子是否为地雷。这样我们就可以根据信息递推状态转移方程,具体见代码:

#include<cstdio>
#define LL long long
#define For(i, a, b) for(register int i = a; i <= b; ++i)
using namespace std;
const int maxn = 1e4 + 5;
LL dp[maxn][5];
int num[maxn], now, n;

int main() {
    scanf("%d", &n);
    For(i, 1, n) scanf("%d", &num[i]);
    dp[0][0] = dp[0][1] = 1;
    For(i, 0, n - 1) {
        For(k, 0, 3) {
            now = dp[i][k];
            int G = (k << 1 | 1) % 4, U = (k << 1) % 4;
            if(num[i + 1] == 0 && !(k & 1) && !(k & 2)) 
                dp[i + 1][U] += now;
            if(num[i + 1] == 1) {
                if(k & 2 && !(k & 1)) dp[i + 1][U] += now;
                if(!(k & 2) && k & 1) dp[i + 1][U] += now;
                if(!(k & 2) && !(k & 1)) dp[i + 1][G] += now;
            }
            if(num[i + 1] == 2) {
                if(k & 2 && !(k & 1)) dp[i + 1][G] += now;
                if(k & 1 && !(k & 2)) dp[i + 1][G] += now;
                if((k & 3) == 3) dp[i + 1][U] += now;
            }
            if(num[i + 1] == 3) {
                if((k & 3) == 3) dp[i + 1][G] += now;
            }
        }
        //if(i == 0) dp[1][2] = dp[1][3] = 0;
    }
    printf("%lld", dp[n][0] + dp[n][2]);
    return 0;
}


上一篇: 洛谷P2261 [CQOI2007]余数求和

下一篇: 洛谷P1641 [SCOI2010]生成字符串

371 人读过
立即登录, 发表评论.
没有帐号? 立即注册
0 条评论
文档导航