[ An Ac a Day ^_^ ] POJ 3254 Corn Fields 状压dp
Posted 可是我不配
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ An Ac a Day ^_^ ] POJ 3254 Corn Fields 状压dp相关的知识,希望对你有一定的参考价值。
题意:
有一块n*m的土地
0代表不肥沃不可以放牛 1代表肥沃可以放牛
且相邻的草地不能同时放牛
问最多有多少种放牛的方法并对1e8取模
思路:
典型的状压dp 能状态压缩 能状态转移
能状态压缩的题的特点就是只有两种状态
所以用0 1表示两种状态 用位运算判断是否符合条件
然后将前一行的合理状态转移到后一行
最后统计最后一行的状态
dp[i][j]代表第i行以第j种状态放牛时有多少种不同的状态
(c++的语言特性是 封装 继承 多态~)
1 /* *********************************************** 2 Author :Sun Yuefeng 3 Created Time :2016/10/31 17:59:53 4 File Name :C.cpp 5 ************************************************ */ 6 7 #include<cstdio> 8 #include<iostream> 9 #include<algorithm> 10 #include<cmath> 11 #include<cstring> 12 #include<string> 13 #include<bitset> 14 #include<map> 15 #include<set> 16 #include<stack> 17 #include<vector> 18 #include<queue> 19 #include<list> 20 #define M(a,b) memset(a,b,sizeof(a)) 21 using namespace std; 22 typedef long long ll; 23 const int inf=0x3f3f3f3f; 24 const int maxn=1<<15; 25 const int mod=1e8; 26 int dx[8]= {0,0,1,-1,1,-1,1,-1}; 27 int dy[8]= {1,-1,0,0,-1,1,1,-1}; 28 29 int _map[maxn]; //记录给出的每块地的状态 30 int st[maxn]; //记录每一行的状态 31 int dp[15][maxn]; 32 33 bool judge(int x) //判断相邻两位是否同时为1 34 { 35 return (x&(x<<1)); 36 } 37 38 bool judge(int x,int y) //判断两位是否同时为1 39 { 40 return _map[x]&st[y]; 41 } 42 43 int main() 44 { 45 //freopen("in.txt","r",stdin); 46 //freopen("out.txt","w",stdout); 47 int n,m; 48 while(cin>>n>>m){ 49 int x; 50 M(dp,0),M(_map,0),M(st,0); 51 for(int i=0;i<n;i++) 52 { 53 for(int j=0;j<m;j++) 54 { 55 cin>>x; 56 if(!x) 57 { 58 _map[i]+=(1<<j); //向图中添加空地 59 } 60 } 61 } 62 int k=0; 63 for(int i=0;i<(1<<m);i++) //初始化能不能以i状态放牛 64 { 65 if(!judge(i)) 66 { 67 st[k++]=i; 68 } 69 } 70 for(int i=0;i<k;i++) //初始化第一行状态 71 { 72 dp[0][i]=(!judge(0,i)); 73 } 74 for(int i=1;i<n;i++) 75 { 76 for(int j=0;j<k;j++) 77 { 78 if(judge(i,j)) continue; //判断第i行是否能以j的方式放牛 79 for(int l=0;l<k;l++) 80 { 81 if(judge(i-1,l)) continue; //判断上一行状态 82 if(!(st[j]&st[l])) //符合题意转移状态 83 dp[i][j]+=dp[i-1][l]; 84 } 85 } 86 } 87 int ans=0; 88 for(int i=0;i<k;i++) 89 { 90 ans+=dp[n-1][i]; 91 ans%=mod; 92 } 93 cout<<ans<<endl; 94 } 95 return 0; 96 }
以上是关于[ An Ac a Day ^_^ ] POJ 3254 Corn Fields 状压dp的主要内容,如果未能解决你的问题,请参考以下文章
[ An Ac a Day ^_^ ][kuangbin带你飞]专题四 最短路练习 POJ 2240 Arbitrage spfa求负环
[ An Ac a Day ^_^ ] hdu 1003 dp
[ An Ac a Day ^_^ ] hdu 1662 数据结构 二叉树
[ An Ac a Day ^_^ ] hdu 2553 N皇后问题 搜索