poj3254(Corn Fields)状压dp

来源:互联网 发布:小甲鱼c语言新版 编辑:程序博客网 时间:2024/05/20 08:42

题意:在n*m(1<=n,m<=12)的矩阵上种植玉米,任意共边的方格不能同时种,并且有些特定方格也不能种。问能有多少种种植的方案;


解法;很经典的状压模型。先将每一行的合法状态求出来,12的时候最多377个合法状态。然后进行与行之间的状态转移。最坏复杂度12*(377^2)


代码:

/***************************************************** author:xiefubao*******************************************************/#pragma comment(linker, "/STACK:102400000,102400000")#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>#include <vector>#include <algorithm>#include <cmath>#include <map>#include <set>#include <stack>#include <string.h>using namespace std;#define eps 1e-8typedef long long LL;int inf= 100000000;int rem[15][15];int legal[10000];int p=0;int n,m;int num[20];bool OK(int k){    return !(k&(k<<1));}int ans[20][10000];int main(){  scanf("%d%d",&n,&m);  for(int i=0;i<n;i++)    for(int j=0;j<m;j++)  {      scanf("%d",rem[i]+j);      if(rem[i][j]==0)      num[i]+=1<<j;  }  for(int i=0;i<(1<<m);i++)  {      if(OK(i))        legal[p++]=i;  }  cout<<p<<endl;  for(int i=0;i<p;i++)  {      if((legal[i]&num[0])==0)        ans[0][i]=1;  }  for(int i=1;i<n;i++)  {      for(int j=0;j<p;j++)      {          for(int k=0;k<p;k++)          {            if(((legal[j]&legal[k])==0)&&(legal[k]&num[i])==0)                ans[i][k]=(ans[i][k]+ans[i-1][j])%inf;          }      }  }  int out=0;  for(int i=0;i<p;i++)  {      out=(out+ans[n-1][i])%inf;  }  cout<<out<<endl;   return 0;}

0 0
原创粉丝点击