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

[ An Ac a Day ^_^ ] POJ 3254 Corn Fields 状压dp

时间:2016-10-31 20:45:53      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:运算   define   end   特性   位运算   nbsp   inf   bitset   bool   

题意:

有一块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

标签:运算   define   end   特性   位运算   nbsp   inf   bitset   bool   

原文地址:http://www.cnblogs.com/general10/p/6016956.html

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