[BZOJ1725][Usaco2006 Nov]Corn Fields牧场的安排(状压dp)
2016-04-24 22:10
507 查看
题目描述
传送门题解
预处理出状态每一行是否可行、两两关系是否可行。状态:f[i][j]表示种到第i行,第i行状态为j的方案数。
转移:f[i][j]=(f[i][j]+f[i-1][k])%Mod;j和k分别表示这一行和上一行的状态。
初始化:f[1][所有状态]=1,其余为0
目标:∑i=0totf[n][i]其中tot为状态总数
代码
#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int N=13; const int Mod=1e8; int n,m,tot,x,s[N],mi[N],state[N],f[N][1<<(N-1)],ans; bool line[1<<(N-1)],ok[1<<(N-1)][1<<(N-1)],situ[N][1<<(N-1)]; int main(){ mi[0]=1; for (int i=1;i<N;++i) mi[i]=mi[i-1]<<1; scanf("%d%d",&n,&m); tot=(1<<m)-1; for (int i=1;i<=n;++i){ for (int j=m;j>=1;--j) scanf("%d",&s[j]); x=0; for (int j=1;j<=m;++j) x+=mi[j-1]*s[j]; state[i]=x; } for (int i=0;i<=tot;++i) if (((i>>1)&i)==0) line[i]=true; for (int i=0;i<=tot;++i) if (line[i]) for (int j=0;j<=tot;++j) if (line[j]) if ((i&j)==0) ok[i][j]=true; for (int i=1;i<=n;++i) for (int j=0;j<=tot;++j) if ((state[i]|j)==state[i]) situ[i][j]=true; for (int i=0;i<=tot;++i) if (situ[1][i]&&line[i]) f[1][i]=1; for (int i=2;i<=n;++i) for (int j=0;j<=tot;++j) if (line[j]&&situ[i][j]) for (int k=0;k<=tot;++k) if (line[k]&&situ[i-1][k]) if (ok[j][k]) f[i][j]=(f[i][j]+f[i-1][k])%Mod; for (int i=0;i<=tot;++i) ans=(ans+f [i])%Mod; printf("%d\n",ans); }
总结
内存算好!本来1A的题手残内存多打了嘿嘿嘿
相关文章推荐
- Android webview使用详解
- Spark1.3.0安装配置及WordCount示例
- 两个Python web框架:Django & Tornado比较
- hdu 2353 n皇后问题
- 配置JDBC事务\配置hibernate事务
- Java并发:等待事件发生后所有线程继续执行
- js关于setTimeout实现延时执行函数并进行传参
- Paxos算法
- 循环队列的基本操作
- hdu5673 Robot
- Hibernate4实战 之 第二部分:Hibernate的基本配置
- CQOI2016 密钥破解 pollard-rho
- android.webkit.WebView/WebViewClient/WebChromeClient
- http请求和消息
- linux常用查看硬件设备信息命令
- LeetCode *** 79. Word Search
- 机器学习基石第七讲:the vc dimension
- jQuery EasyUI之Form表单提交
- 如何应用assets下的文件
- 链栈的基本操作