poj3254 玉米地(状压dp)
src:http://poj.org/problem?id=3254
ac代码:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<stdio.h> #include <cstdlib> #include<malloc.h> #include<algorithm> #include<functional> #include<utility> #include<cmath> #include<Map> #include<string.h> #include<string> #include<vector> #include<stack> #include<set> #include<queue> #include<list> //#include<bits/stdc++.h> using namespace std; int Max(int a, int b) { return a > b ? a : b; } int Min(int a, int b) { return a > b ? b : a; } #define FOR(i,a,b) for(int i=a;i<=b;i++) typedef long long LL; typedef unsigned long long ull; const double INF = 99999999999.0; const double eps = 1e-6; const int mo=100000000; #define siz 13 int n,m,state[400],cur[siz],total,nlegal,dp[siz][400];//state开377以上就行,因为可行状态就n==12时最大377个!!! void init() { memset(dp,0,sizeof(dp)); memset(cur,0,sizeof(cur)); total=nlegal=0; total=1<<n; FOR(i,0,total-1)if(!(i&i<<1))state[++nlegal]=i;//记录枚举的合法状态 //为什么用i左移和i判断呢、因为如果某位和它右边冲突的话,那它右边那位就会通过左移判断出来!!! } int main() { std::ios::sync_with_stdio(false); cin>>m>>n; int fg; init(); //cout<<nlegal<<endl; FOR(i,1,m)FOR(j,1,n){ cin>>fg; if(!fg)cur[i]+=1<<(j-1);//0表示这块地fertile可行 }//cur用0表可行好处:这样可行的state的1只能分布在cur的0的位置上,这样&为0则判断出state可行,更方便哦~~~ //FOR(i,1,nlegal)cout<<state[i]<<' ';cout<<endl;// //cout<<"cur[1] "<<cur[1]<<endl;// for(int i=1;i<=nlegal;i++){//初始化dp if(!(state[i]&cur[1])){dp[1][i]=1;} } for(int i=2;i<=m;i++){ for(int j=1;j<=nlegal;j++){ if(!(state[j]&cur[i])){ for(int k=1;k<=nlegal;k++){ if(state[k]&cur[i-1])continue; if(state[j]&state[k])continue; dp[i][j]=(dp[i][j]+dp[i-1][k])%mo; } } } } int ans=0; FOR(i,1,nlegal){ ans=(ans+dp[m][i])%mo; } cout<<ans<<endl; return 0; }

浙公网安备 33010602011771号