【SCOI2005】【BZOJ1087】互不侵犯King
2015-08-28 09:35
337 查看
我天生不喜欢Dp就算你是状压DP…
Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
Input
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
Output
方案数。
Sample Input
3 2
Sample Output
16
HINT
Source
其实这是我的第一道状压DP…
设f[i][j][k]为到了第i行已经放了k个国王,当前行状态为k
二进制表示国王的放置位置.
然后可以进行O(nk22n)O(nk2^{2n})转移
最后求一个sum就是答案
Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
Input
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
Output
方案数。
Sample Input
3 2
Sample Output
16
HINT
Source
其实这是我的第一道状压DP…
设f[i][j][k]为到了第i行已经放了k个国王,当前行状态为k
二进制表示国王的放置位置.
然后可以进行O(nk22n)O(nk2^{2n})转移
最后求一个sum就是答案
[code]#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define MAXN 1024 #define LL long long using namespace std; int n,k; LL ans,f[15][100][MAXN]; inline bool check(int x,int y) { return !((x&(y<<1))||(x&(y>>1))||(x&y)); } inline bool Check(int x) { return !((x&(x<<1))||(x&(x>>1))); } inline int get(int x) { int ret=0; for (int i=x;i;i>>=1) if (i&1) ret++; return ret; } int main() { scanf("%d%d",&n,&k); int Max=(1<<n)-1; for (int i=0;i<=Max;i++) if (Check(i)) f[1][get(i)][i]=1; for (int i=2;i<=n;i++) for (int j=0;j<=k;j++) for (int l=0;l<=Max;l++) if (Check(l)&&j>=get(l)) { int tmp=get(l); for (int t=0;t<=Max;t++) if (Check(t)&&check(l,t)) f[i][j][l]+=f[i-1][j-tmp][t]; } for (int i=0;i<=Max;i++) if (Check(i)) ans+=f [k][i]; printf("%lld\n",ans); }
相关文章推荐
- 【来日复制粘贴】状态栏随机显示
- java网页错误
- 关于iis7短日期后面带有星期的解决办法
- 扫盲知识点
- 代码规范
- 【排序算法】选择排序
- select 实现分析 –2 【整理】
- POJ 2575 Jolly Jumpers(水~)
- poj 2031(prim)
- 让jquery弹出窗口不被阻挡
- ubuntu虚拟机配置
- ubuntu 下apt-get update 遇到Encountered a section with no Package: header
- CoreAnimation-01-CALayer核心要点及实例解析
- IOS简单的选择器实现UIPickerView(省+市+区)
- jsp、servlet笔记
- Linux中通过命令行监控股票报价
- linux c 连接mysql数据库
- iOS9适配之Bitcode错误
- C#泛型详解
- 《第一行代码》读书笔记(一)----活动