洛谷p1879玉米田

原題

看取膜的數就知道暴搜死定,那麼用狀壓,f[i][j]表示可以轉移到i行j狀態的方案數,和互不侵犯類似,但由於提前有賦值,所以把1和0換一下可以更方便的判斷推導。

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int m,n;
bool a[14][14];int b[14],f[14][9000];
int dfs(int x,int y,int zhuang,int net,int l,int old)
{
    if(y>=n)
    {
        f[x+1][(net|b[x+1])]=(f[x+1][(net|b[x+1])]+old)%100000000;
        return 0;
    }
    if(y-l>1&&((1<<y)&zhuang)==0)
    {
        int k=net;
        k=k|(1<<y);
        dfs(x,y+2,zhuang,k,y,old);
    }
    dfs(x,y+1,zhuang,net,l,old);
}
int main()
{
    cin>>m>>n;
    for(int i=1;i<=m;++i)
     for(int j=1;j<=n;++j)
     cin>>a[i][j];
    for(int i=1;i<=m;++i)
    {
        b[i]=0;
        for(int j=1;j<=n;++j)
        {
            if(a[i][j]==1)
            a[i][j]=0;
            else a[i][j]=1;
            b[i]<<=1;
            b[i]+=a[i][j];
        }
    }
    f[1][b[1]]=1;  //從f【0】【0】推也可以
    for(int i=1;i<=m;++i)
     for(int j=0;j<(1<<n);++j)
      if(f[i][j])
      {
          dfs(i,0,j,0,-2,f[i][j]);
      }
    int ans=0;
    for(int i=0;i<(1<<n);++i)
    ans=(ans+f[m+1][i])%100000000;
    cout<<ans;
    return 0;
} 



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