[bzoj1087][scoi2005]互不侵犯king
题目大意
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上
左下右上右下八个方向上附近的各一个格子,共8个格子。
思路
首先,搜索可以放弃,因为这是一个计数问题,正解几乎不可能是搜索。
我们考虑这样一个决策过程:对于每一行,我们决定放哪些格子。这个决策过程很明显满足无后效性和最优子结构,同时,根据上一行可以递推出这一行的所有可行方案。
所以,我们考虑使用动态规划。
怎么划分阶段呢?根据我们以上的推理,很显然可以根据行来划分阶段。
怎么转移呢?在转移的时候,我们要考虑放的king的个数,所以要把king的个数加入状态。其次,为了让king互不侵犯,我们要存储这一行里哪些格子放了king,用一个二进制状态存储,写入状态。
很容易写出转移方程。
f[i][j][s] += f[i-1][j-cnt[j]][pre] 事实上,这更像一个递推。
下面给出代码。
Code
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10;
const int maxs = (1 << 10) + 1;
int n, k, stat[maxs], m = 0;
bool mp[maxs][maxs];
long long f[maxn][maxn * maxn][maxs];
int ct[maxs];
void dfs(int p, int cnt, int x) {
if (p >= n || cnt > k)
return;
stat[m++] = x;
ct[m - 1] = cnt;
for (int i = p + 1; i < n; i++) {
if (abs(p - i) > 1 || p == -1)
dfs(i, cnt + 1, x | (1 << i));
}
}
int main() {
scanf("%d%d", &n, &k);
dfs(0 - 1, 0, 0);
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
mp[i][j] = mp[j][i] = (stat[i] & stat[j]) || (stat[i] >> 1 & stat[j]) ||
(stat[j] >> 1 & stat[i])
? 0
: 1;
}
}
for (int i = 0; i < m; i++) {
f[0][ct[i]][i] = 1LL;
}
for (int i = 1; i < n; i++) {
for (int j = 0; j <= k; j++) {
for (int now = 0; now < m; now++) {
if (ct[now] > j)
continue;
for (int l = 0; l < m; l++) {
if (mp[l][now] && ct[l] + ct[now] <= j) {
f[i][j][now] += f[i - 1][j - ct[now]][l];
}
}
}
}
}
long long ans = 0;
for (int i = 0; i < m; i++) {
ans += f[n - 1][k][i];
}
printf("%lld", ans);
return 0;
}
[bzoj1087][scoi2005]互不侵犯king的更多相关文章
- BZOJ1087 SCOI2005 互不侵犯King 【状压DP】
BZOJ1087 SCOI2005 互不侵犯King Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附 ...
- 状压入门--bzoj1087: [SCOI2005]互不侵犯King【状压dp】
Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上 左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行, ...
- [BZOJ1087][SCOI2005]互不侵犯King解题报告|状压DP
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 好像若干月前非常Naive地去写过DFS... ...
- [BZOJ1087] [SCOI2005] 互不侵犯King (状压dp)
Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包 ...
- BZOJ1087 [SCOI2005]互不侵犯King 状态压缩动态规划
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1087 题意概括 在n*n的棋盘上面放k个国王,使得他们互相无法攻击,问有多少种摆法. 题解 dp[ ...
- bzoj1087: [SCOI2005]互不侵犯King (codevs2451) 状压dp
唔...今天学了状压就练练手... 点我看题 这题的话,我感觉算是入门题了QAQ... 然而我还是想了好久... 大致自己推出了方程,但是一直挂,调了很久选择了题解 坚持不懈的努力的调代码. 然后发现 ...
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
- SCOI2005互不侵犯King
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1499 Solved: 872[Submit][S ...
- 洛谷1377 M国王 (SCOI2005互不侵犯King)
洛谷1377 M国王 (SCOI2005互不侵犯King) 本题地址:http://www.luogu.org/problem/show?pid=1377 题目描述 天天都是n皇后,多么无聊啊.我们来 ...
随机推荐
- 理解记忆三种常见字符编码:ASCII, Unicode,UTF-8
理解什么是字符编码? 计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是25 ...
- Python None comparison: should I use “is” or ==?
Use is when you want to check against an object's identity (e.g. checking to see if var is None). Us ...
- Java批量文件打包下载
经常遇到选择多个文件进行批量下载的情况,可以先将选择的所有的文件生成一个zip文件,然后再下载,该zip文件,即可实现批量下载,但是在打包过程中,常常也会出现下载过来的zip文件中里面有乱码的文件名, ...
- web应用 http 响应 url uri
动态web 应用结构 WEB-INF --classes --lib web.xml 响应: url uri
- .NET LINQ查询操作中的类型关系
LINQ 查询操作中的类型关系 若要有效编写查询,您应该了解完整的查询操作中的变量类型是如何全部彼此关联的. 如果您了解这些关系,就能够更容易地理解文档中的 LINQ 示例和代码示例. 另外 ...
- 如何使用videojs兼容IE8浏览器
需要在服务器下运行 首先我们需要下载videojs包 https://github.com/videojs/video.js/releases 这里简单写了一个小栗子 <!DOCTYPE htm ...
- JavaScript链表
//实现列表类 function list() { this.listSize = 0;//元素个数 属性 this.pos = 0;//当前位置 属性 ...
- Linux网络管理2---(网络环境查看命令、网络测试命令)
1.网络环境查看命令 ifconfig命令 查看或临时修改网络状态的命令 可以看到IP.子网掩码……信息 关闭和启动网卡 ifdown 网卡设备名(比如: ifdown eth0):禁用该网卡设备 i ...
- acm数学(待续)
意图写出http://www.cnblogs.com/kuangbin/archive/2012/08/28/2661066.html这个东西的完善版. 1.置换,置换的运算 poj 2369 Per ...
- js实现复制到剪贴板功能,兼容所有浏览器
http://www.cnblogs.com/PeunZhang/p/3324727.html https://github.com/zeroclipboard/ZeroClipboard 复制链接到 ...