poj3254

题意:一个row*col的矩阵,每个格子是0或者1,1表示土壤肥沃可以种植草地,0则不可以。在种草地的格子可以放牛,但边相邻的两个格子不允许同时放牛,问总共有多少种放牛的方法?(不放牛也算一种情况)

思路:状态压缩DP。在做了状态压缩的入门poj1185的炮兵阵地之后,再做状态DP就有章可循了,基本上很多的函数或者变量都是相通的,这里也不详解了。DP部分:dp[i][k]表示第r行处于状态k时,前r行的情况数总和。这点应该在打代码前就先明确,一开始很模糊还去求sum[i],栽了一次。

源代码:(248K, 0MS)

#include<iostream>
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
const int MAX = 400;
const int MOD = 100000000;

int map[12];
int cnt = 0, stk[MAX];
int dp[12][MAX];

bool ok(int x){
    if(x & (x<<1)) return false;
    return true;
}

void findStk(int n){
    for(int i = 0; i < (1<<n); i ++)
        if(ok(i))
            stk[cnt ++] = i;
}

int main(){
    int row, col, r, c, i, j;
    memset(dp, 0, sizeof(dp));
    cin >> row >> col;
    findStk(col);
    for(r = 0; r < row; r ++)
        for(c = 0; c < col; c ++){
            int tmp;
            cin >> tmp;
            if(tmp == 0) map[r] |= (1<<c);
        }
    for(i = 0; i < cnt; i ++)
        if(!(map[0]&stk[i]))
            dp[0][i] = 1;
    for(r = 1; r < row; r ++)
        for(i = 0; i < cnt; i ++){
            if(map[r]&stk[i]) continue;
            for(j = 0; j < cnt; j ++){
                if(map[r-1]&stk[j] || stk[i]&stk[j]) continue;
                dp[r][i] = (dp[r][i]+dp[r-1][j])%MOD;
            }
        }
    int ans = 0;
    for(i = 0; i < cnt; i ++)
        if(dp[row-1][i] != -1)
            ans = (ans+dp[row-1][i])%MOD;
    cout << ans << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值