码迷,mamicode.com
首页 > 其他好文 > 详细

poj3254(Corn Fields)状压dp

时间:2014-05-04 09:21:40      阅读:301      评论:0      收藏:0      [点我收藏+]

标签:style   blog   class   code   int   string   

题意:在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-8
typedef 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;
}

poj3254(Corn Fields)状压dp,布布扣,bubuko.com

poj3254(Corn Fields)状压dp

标签:style   blog   class   code   int   string   

原文地址:http://blog.csdn.net/xiefubao/article/details/24934413

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!