【BZOJ】1087: [SCOI2005]互不侵犯King
2016-09-12 20:05
274 查看
【算法】状态压缩型DP
【题解】http://www.cnblogs.com/xtx1999/p/4620227.html (orz)
https://www.cnblogs.com/zbtrs/p/6189240.html
dp[i][j][k]为前i行已经放了j个国王并且第i行的状态为k(二进制)的方案数。
状态左移右移预处理两行合法。
dp[i][j][k] = Σdp[i-1][j - num[k]][p]
#include<cstdio> #include<algorithm> using namespace std; const int maxn=10,e2=530; long long f[maxn][e2][maxn*maxn]; int n,mk,num[e2],king[e2],ok[e2][e2]; bool selfcheck(int a) { return !(a&(a>>1)); } int calc(int a) { int cyc=0; while(a) { if(a&1)cyc++; a=a>>1; } return cyc; } bool check(int a,int b) { if((a&b)||(a&(b<<1))||(a&(b>>1)))return 0; return 1; } int main() { scanf("%d%d",&n,&mk); int all=(1<<n)-1,tot=0; for(int i=0;i<=all;i++) { if(selfcheck(i)) { num[++tot]=i; king[tot]=calc(i); //printf("%d\n",i); } } for(int i=1;i<=tot;i++) for(int j=1;j<=tot;j++) if(!ok[i][j])if(check(num[i],num[j])) ok[i][j]=ok[j][i]=1;//,printf("%d %d\n",i,j); f[0][1][0]=1; for(int i=0;i<=n-1;i++) for(int j=1;j<=tot;j++) for(int k=0;k<=mk;k++) if(f[i][j][k]) for(int p=1;p<=tot;p++) if(ok[j]View Code [p]&&k+king[p]<=mk) f[i+1][p][k+king[p]]+=f[i][j][k]; long long ans=0; for(int i=1;i<=tot;i++) ans+=f [i][mk]; printf("%lld",ans); return 0; }
相关文章推荐
- CSS编码规范 百度
- 关于c++继承
- LeetCode 389:Find the Difference
- 动态创建元素
- 51nod-1109 01组成的N的倍数(宽搜)
- Hadoop Yarn源码 - day1
- 36. Valid Sudoku
- 乘法逆元小结
- 《GPU高性能编程CUDA实战》学习笔记(七)
- 商业化IM 客户端接口设计分析
- 【LightOJ 1030】Discovering Gold(期望DP)
- 剪切板的操作
- HDU 5874 Friends and Enemies(二分图思想)——2016 ACM/ICPC Asia Regional Dalian Online
- JAVA 方法定义及调用
- Android存储--ContentProvider
- C++: Perfect Forwarding
- HDU-1042 N!
- 理解金纳米晶体的光热转换效率
- commons-logging与log4j学习总结
- [verilog读书笔记]6.数据流建模