zoukankan      html  css  js  c++  java
  • 【POJ3254】Corn Fields

    http://poj.org/problem?id=3254

    题意:给你一块n*m(0<n,m<=12)的地图,其中有的方格是肥沃的(用1表示),有的方格是贫瘠的(用0表示)。现在约翰要在肥沃的土地上放奶牛,且要求不能有两个奶牛相邻,请问有多少种方案数。

    状压DP入门题。

    首先预处理每一行不考虑贫瘠地时所有可行的放置状态,用states数组存着。

    然后令f(i,j)为考虑前i行且第i行放置状态为states[j]时的方案数,可得f(i, j)=sigma{f(i-1, k) | states[j]&states[k]==0} (states[j]不包含第j行的贫瘠地),f(i, j)=0(states[j]包含第j行的贫瘠地)。

    先计算第一行的方案数,再递推第二行到第n行的方案数,最后答案为sigma{f(n,j)}。具体实现看代码

    #include <iostream>
    #include <vector>
    using namespace std;
    template <class T>
    void update(T &x)
    {
        while (x >= 100000000)
            x -= 100000000;
    }
    int r, c, map[13];            // 初始地图
    int states[1 << 13], siz = 0; // 不考虑贫瘠地时每一行的所有可行放置方案
    int dp[13][1 << 13];          // dp[i][j]表示考虑前i行且第i行放置状态为states[j]时的方案数
    int main()
    {
        ios::sync_with_stdio(false);
        cin >> r >> c;
        for (int i = 0; i < 1 << c; i++)
            if (!(i & (i << 1))) // 若状态i不存在两个相邻的1
                states[++siz] = i;
    
        int a;
        for (int i = 1; i <= r; i++)
        {
            for (int j = 0; j < c; j++)
            {
                cin >> a;
                if (!a)
                    map[i] |= (1 << j);
            }
        }
    
        for (int i = 1; i <= siz; i++)
            if (!(states[i] & map[1])) // 若状态states[i]不包含第一行的贫瘠地,则出现一种放置方案
                dp[1][i] = 1;
    
        for (int i = 2; i <= r; i++)
        {
            for (int j = 1; j <= siz; j++) // 枚举这一行的放置方案
            {
                if (states[j] & map[i]) // 若状态states[j]包含第i行的贫瘠地
                    continue;
                for (int k = 1; k <= siz; k++) // 枚举上一行的放置方案
                {
                    if (states[k] & states[j]) // 若状态states[k]与状态states[j]有相同位置的1
                        continue;
                    update(dp[i][j] += dp[i - 1][k]);
                }
            }
        }
    
        int ans = 0;
        for (int i = 1; i <= siz; i++)
            update(ans += dp[r][i]);
        cout << ans;
        return 0;
    }
  • 相关阅读:
    2017博普杯 东北大学邀请赛(B. Drink too much water)(贪心+树链剖分)
    AGC018D Tree and Hamilton Path(树+树的重心)
    BZOJ2843:极地旅行社
    P++ 1.0.5
    BZOJ1052:[HAOI2007]覆盖问题
    BZOJ3098:Hash Killer II
    BZOJ2784:[JLOI2012]时间流逝
    BZOJ2282:[SDOI2011]消防
    BZOJ1875:[SDOI2009]HH去散步
    Codeforces 504 A (Round #285 div.1 A) Misha and Forest
  • 原文地址:https://www.cnblogs.com/ssttkkl/p/7624842.html
Copyright © 2011-2022 走看看