您的位置:首页 > 其它

POJ 3254 Corn Fields(状态压缩dp)

2014-03-30 08:13 399 查看
题目链接:POJ 3254 Corn Fields

状态压缩dp。

state存储每一行可能的状态,limit存储某一行的限制的相反。注意&运算和两个数组的关系。

状态转移方程:dp[i][j]=sum{dp[i-1][k]}(其中k为上一行的合法方案,并且不合方案j冲突)。

状压dp好神奇。。

#include <iostream>
#include <cstring>

using namespace std;

const int MOD = 100000000;
const int MAX_N = 12 + 3;
const int MAX_M = 1 << MAX_N;
int n, m, cnt, dp[MAX_N][MAX_M], state[MAX_M], limit[MAX_M];

bool ok(int x)
{
    if(x & (x << 1))
        return false;
    return true;
}
void getState(int n)
{
    for(int i = 0;i < (1 << n);i++)
    {
        if(ok(i))
            state[cnt++] = i;
    }
}

int main()
{
    memset(dp,0,sizeof(dp));
    cin >> n >> m;
    getState(m);
    int temp;
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            cin >> temp;
            if(temp == 0)
                limit[i] |= (1 << j);
        }
    }
    for(int i = 0; i < cnt; i++)
        if(!(limit[0] & state[i]))
            dp[0][i] = 1;
    for(int i = 1; i < n; i++)
    {
        for(int j = 0; j < cnt;j++)
        {
            if(limit[i] & state[j])
                continue;
            for(int k = 0; k < cnt;k++)
            {
                if(limit[i - 1] & state[k] || state[j] & state[k])
                    continue;
                dp[i][j] = (dp[i][j] + dp[i - 1][k]) % MOD;
            }
        }
    }
    int ans = 0;
    for(int i = 0; i < cnt; i++)
        ans = (ans + dp[n - 1][i]) % MOD;
    cout << ans << endl;
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: