POJ 3254-狀壓dp

題意:輸入m行n列的數字,其中爲1或者是0
1表示土壤肥沃可以種植草地,0則不可以。
在種草地的區域可以放牛,但相鄰的兩
塊區域不允許同時放牛,問有多少种放牛的方法?
(不放牛也算一種情況)

分析:
 由m,n<=12,可用狀態壓縮
 對於第i行,可以放草的格子置爲0,不可以種草的格子設置爲1,整一行的狀態存入graph[i]中
 對於每一行,放牛的格爲1,不放牛的格爲0,整行用一個二進制數表示
 dp[i][j]表示第i行放牛狀態爲j時有多少種方法,易知:
 1.首先j必須合法,即左右相鄰兩位不同時出現1,
 2.不能在不能種草的地方放牛,即j&graph[i]==0
 3.dp[i][j] = Sigma(dp[i-1][k]),其中k&j==0,即上下相鄰位置不放牛

由此,可以求出所有的dp[i][j],那麼放牛的種類共有 = Sigma(dp[n][j])最後一行所有狀態的放牛種類之和

/****************************
* author:crazy_石頭
* date:2014/04/29
* time:32 ms
* algorithm:狀壓dp 
* Pro:POJ 3254
***************************/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
 
using namespace std;
 
#define INF INT_MAX
#define eps 1e-8
#define A system("pause")
#define rep(i,h,n) for(int i=(h);i<=(n);i++)
#define ms(a,b) memset((a),(b),sizeof(a))
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define LL long long
#define mod 100000000
const int maxn=20;
const int maxm=600+10;
int dp[maxn][maxm],state[maxm],cur[maxm];
int n,m,cnt=0;

inline int connected(int x)
{
       if(x&(x<<1)) return 0;
       return 1;
}//檢查奶牛放置情形是否合理,即是否有相鄰的兩個1,沒有返回true

inline void prepare()
{
       int all=(1<>m>>n)
    {
        prepare();ms(dp,0);
        rep(i,1,m)
        {
            cur[i]=0;//記錄第i行土地的土壤狀態
            rep(j,1,n)
            {
                 int x;
                 cin>>x;
                 if(!x) cur[i]+=(1<<(n-j));
            }
        }
        rep(i,1,cnt)  if(ok(state[i],1)) dp[1][i]=1;
        rep(i,2,m)
        {
            rep(k,1,cnt)
            {
                if(!ok(state[k],i))continue;
                rep(j,1,cnt)
                {
                    if(!ok(state[j],i-1))continue;
                    if(state[k]&state[j])continue;
                    dp[i][k] = (dp[i][k] + dp[i-1][j])%mod;
                }
            }
        }
        int ans = 0;
        for(int i = 1; i <= cnt; ++i)
            ans = (ans + dp[m][i])%mod;
        printf("%d\n",ans);
    }
}    
        

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章