POJ 3254 Corn Fields(状压dp)
2013-07-05 14:41
381 查看
题目大意:有一个牧场,1代表可以放牧,0代表不可以放牧。而且不不可以带连续的牧场上同时放牧。
思路:状态压缩来表示放牧的状态。。。然后上代码。
过了一年从新写这道题。
去年什么都不会,就照着别人的版子抄。
思路分析:
状态方程:dp[i][state] 表示递推到第 i 行前面都不冲突的前提之下,第 i 行的状态为state的种数。
转移方程:dp[i][state] = segma( dp[i-1][s]) s的状态要和地图不冲突 , 也要和state 不冲突。
然后用位运算的技巧对地图判断冲突。
这是13年的代码了。。。好怀旧- -
思路:状态压缩来表示放牧的状态。。。然后上代码。
过了一年从新写这道题。
去年什么都不会,就照着别人的版子抄。
思路分析:
状态方程:dp[i][state] 表示递推到第 i 行前面都不冲突的前提之下,第 i 行的状态为state的种数。
转移方程:dp[i][state] = segma( dp[i-1][s]) s的状态要和地图不冲突 , 也要和state 不冲突。
然后用位运算的技巧对地图判断冲突。
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int mod = 100000000; bool cando[1<<12]; int a[20]; int dp[20][1<<12]; int main() { for(int s=0;s<(1<<12);s++) { cando[s]=true; for(int i=0;i<11;i++) { if(((1<<i)&s) && ((1<<i+1)&s)) cando[s]=false; } } int n,m; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { int b; scanf("%d",&b); if(b)a[i]|=(1<<j); } } memset(dp,0,sizeof dp); for(int s=0;s<(1<<m);s++) { if(cando[s] && (s | a[0])==a[0])dp[0][s]=1; } for(int i=1;i<n;i++) { for(int last=0;last<(1<<m);last++) { if(cando[last] && (last | a[i-1])==a[i-1]) { for(int cur=0;cur<(1<<m);cur++) { if(cando[cur] && (cur | a[i])==a[i]) { if((cur&last)==0) { dp[i][cur]=dp[i][cur]+dp[i-1][last]; dp[i][cur]%=mod; } } } } } } int ans=0; for(int s=0;s<(1<<m);s++) { if(cando[s]) { ans+=dp[n-1][s]; ans%=mod; } } printf("%d\n",ans); } return 0; }
这是13年的代码了。。。好怀旧- -
#include <cstdio> #include <iostream> #include <vector> #include <cstring> const int mod = 100000000; using namespace std; int n,m; int cur[20]; int dp[20][1<<12]; //代表第一行到第I行的总和 vector <int> s; int main() { while(scanf("%d%d",&n,&m)!=EOF) { s.clear(); memset(dp,0,sizeof(dp)); memset(cur,0,sizeof(cur)); int tmp=1<<m; for(int i=0;i<tmp;i++) if((i&(i<<1)) == 0)s.push_back(i);//这是每一行允许的放牧状态 奖i左移一位再与i取并 可以判断是否有连续的1 如果没有的话就加入允许状态里 for(int i=1;i<=n;i++) { cur[i]=0; int num; for(int j=1;j<=m;j++) { scanf("%d",&num); if(!num)cur[i]+=(1<<(m-j)); //对每一行取反 取反之后便可以判断是否合理放牧 } } for(int i=0;i<s.size();i++)//找出第一行可以放牧的状态 { if((s[i] & cur[1]) == 0) dp[1][i]=1; } for(int i=2;i<=n;i++) //从第二行开始DP for(int j=0;j<s.size();j++) //在第i行放入J状态 { if((s[j] & cur[i])==0)//判断J状态是否满足第一行的合理放牧 { for(int k=0;k<s.size();k++)//在第i-1 行放入K状态 { if((s[k] & cur[i-1])==0 && (s[k] & s[j])==0)//判断 第i-1行是否合理放牧 并判断与第i行是否有连续的放牧区域 dp[i][j]=(dp[i][j] + dp[i-1][k])%mod;//递推 } } } int ans=0; for(int i=0;i<s.size();i++) ans=(ans + dp [i])%mod;//找出第N行所有的状态之和 printf("%d\n",ans); } return 0; }
相关文章推荐
- POJ 3254 Corn Fields 状压dp入门
- poj 3254 Corn Fields (状压DP)
- POJ 3254 Corn Fields(状压DP入门)
- POJ 3254 Corn Fields(状压dp)
- poj-3254 Corn Fields(状压dp)
- poj 3254 Corn Fields 状压dp入门
- poj 3254 Corn Fields(他们说是状压dp??)
- POJ 3254 (状压DP) Corn Fields
- poj 3254 Corn Fields(动态规划:状压DP)
- POJ 3254 - Corn Fields (状压DP)
- POJ 3254 Corn Fields (状压DP入门)
- Poj 3254 Corn Fields(状压DP)
- POJ 3254 Corn Fields(状压DP)
- POJ 3254 Corn Fields 状压dp
- POJ 3254 Corn Fields 状压DP
- POJ 3254 Corn Fields(状压DP)
- poj 3254 Corn Fields 【状压 DP 入门】
- poj 3254 Corn Fields 状压dp
- poj3254 Corn Fields (状压DP)
- poj 3254 Corn Fields(状压dp)