BZOJ1725 [Usaco2006 Nov]Corn Fields牧場的安排
阿新 • • 發佈:2018-12-04
題意
Farmer John新買了一塊長方形的牧場,這塊牧場被劃分成M列N行\((1 \leq M \leq 12, 1 \leq N \leq 12)\),每一格都是一塊正方形的土地。FJ打算在牧場上的某幾格土地裡種上美味的草,供他的奶牛們享用。遺憾的是,有些土地相當的貧瘠,不能用來放牧。並且,奶牛們喜歡獨佔一塊草地的感覺,於是FJ不會選擇兩塊相鄰的土地,也就是說,沒有哪兩塊草地有公共邊。當然,FJ還沒有決定在哪些土地上種草。 作為一個好奇的農場主,FJ想知道,如果不考慮草地的總塊數,那麼,一共有多少種種植方案可供他選擇。當然,把新的牧場荒廢,不在任何土地上種草,也算一種方案。請你幫FJ算一下這個總方案數。
分析
狀壓裸題。
就每行建狀態\(f(i,s)\)表示\(i\)行種草狀態為\(s\)的方案數即可。
看到Farmer John和他的奶牛的一般都是水題。
程式碼
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<set> #include<map> #include<queue> #include<stack> #include<algorithm> #include<bitset> #include<cassert> #include<ctime> #include<cstring> #define rg register #define il inline #define co const template<class T>il T read() { rg T data=0; rg int w=1; rg char ch=getchar(); while(!isdigit(ch)) { if(ch=='-') w=-1; ch=getchar(); } while(isdigit(ch)) { data=data*10+ch-'0'; ch=getchar(); } return data*w; } template<class T>T read(T&x) { return x=read<T>(); } using namespace std; typedef long long ll; co int MAXN=12,mod=100000000; int m,n; int mp[MAXN],f[MAXN][1<<MAXN]; int ans; int add(int x,int y) { x+=y; return x>=mod?x-mod:x; } void dp() { for(int i=mp[0];i>=0;i=!i?-1:(i-1)&mp[0]) if((i & (i >> 1)) == 0) f[0][i]=1; for(int i=1;i<m;++i) for(int j=mp[i-1];j>=0;j=!j?-1:(j-1)&mp[i-1]) if(f[i-1][j]) for(int k=mp[i];k>=0;k=!k?-1:(k-1)&mp[i]) if((j & k) == 0 && (k & (k >> 1)) == 0) f[i][k]=add(f[i][k],f[i-1][j]); for(int i=mp[m-1];i>=0;i=!i?-1:(i-1)&mp[m-1]) ans=add(ans,f[m-1][i]); } int main() { // freopen(".in","r",stdin); // freopen(".out","w",stdout); read(m);read(n); for(int i=0;i<m;++i) for(int j=0;j<n;++j) mp[i]=mp[i]<<1|read<int>(); dp(); printf("%d\n",ans); return 0; }