BZOJ 1087 题解【状压DP】
1087: [SCOI2005]互不侵犯King
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 3112 Solved: 1816
[Submit][Status][Discuss]
Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上
左下右上右下八个方向上附近的各一个格子,共8个格子。
Input
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
Output
方案数。
Sample Input
Sample Output
HINT
Solution
这是一道状压DP题,本蒟蒻第一次做状压,坑了好久。
我们用0和1代表棋盘上的某点是否放棋子,每一行的状态都可以用唯一的一个十进制数表示,我们可以通过位运算,得到合法状态数,并统计即可。
DP方程:
f[ i + 1 ][ p + num[ y ] ][ y ] += f[ i ][ p ][ x ]
/**************************************************************
Problem: 1087
User: shadowland
Language: C++
Result: Accepted
Time:40 ms
Memory:6336 kb
****************************************************************/ #include "bits/stdc++.h" using namespace std ;
const int maxNum = ;
const int maxN = ; bool feasible[ maxNum << ] , feasible_flat[ maxNum << ][ maxNum << ] ;
long long f[ maxN ][ ][ maxNum ] , num[ maxNum << ] ; long long Ans ; inline bool Check ( const int x , const int y ) {
if ( ( ( x & y ) == ) && ( ( x & ( y >> ) ) == ) && ( ( x & ( y << ) ) == ) ) return true ;
else return false ;
} void Init ( const int N , const int M ) {
int _cnt = ;
for ( int i= ; i<=( << N ) - ; ++i ) {
if ( ( i & ( i << ) ) == ) {//状态合法记录
_cnt = ;
for ( int Base = i ; Base ; Base >>= ) _cnt += ( Base & ) ;
num[ i ] = _cnt ;//
feasible[ i ] = true ;
}
}
for ( int i= ; i<=( << N ) - ; ++i ) {
if ( feasible[ i ] ) {
for ( int j= ; j<=( << N ) - ; ++j ) {
if ( feasible[ j ] ) {
if ( Check ( i , j ) ) {
feasible_flat[ i ][ j ] = true ;
}
}
}
}
}
} void DEBUG_( int n , int m ) {
printf ( "\n" ) ;
for ( int i= ; i<=( << n ) - ; ++i )
printf ( "%d " , feasible[ i ] ) ; printf ( "\n" ) ;
for ( int i= ; i<=( << n ) - ; ++i ) {
for ( int j= ; j<=( << n ) - ; ++j ) {
printf ( "%d " , feasible_flat[ i ][ j ] ) ;
}
printf ( "\n" ) ;
}
} void DEBUG___( int n , int m ) {
for ( int i= ; i<=n ; ++i ) {
for ( int j= ; j<=( << n ) - ; ++j ) {
for ( int k= ; k<= ( << n ) - ; ++k ) {
printf ( "%d ",f[i][j][k]);
}
}
}
}
int main ( ) {
int N , M ;
scanf ( "%d %d" , &N , &M ) ;
Init( N , M ) ;
for ( int i= ; i<=( << N ) - ; ++i ) {//第一行的所有合法状态
if ( feasible[ i ] ) {
f[ ][ num[ i ] ][ i ] = ;
}
}
for ( int j = ; j<N ; ++j ) {
for ( int x = ; x<= ( << N ) - ; ++x ) {
if ( feasible[ x ] ) {//x状态合法
for ( int y= ; y<= ( << N ) - ; ++y ) {
if ( feasible[ y ] ) {//y状态合法
if ( feasible_flat[ x ][ y ] ) {
for ( int p=num[ x ] ; p + num[ y ] <=M ; ++p ) {
f[ j + ][ p + num[ y ] ][ y ] += f[ j ][ p ][ x ] ;
}
}
}
}
}
}
}
//DEBUG_( N , M ) ;
//DEBUG___( N , M ) ;
for ( int i= ; i<= ( << N ) - ; ++i ) {
Ans += f[ N ][ M ][ i ] ;//统计最终合法状态
}
cout << Ans << endl ;
return ;
}
一定要开long long 。不开long long 见祖宗,十年OI一场空。
2016-10-12 23:20:05
(完)
BZOJ 1087 题解【状压DP】的更多相关文章
- BZOJ 2064: 分裂( 状压dp )
n1+n2次一定可以满足..然后假如之前土地集合S1的子集subs1和之后土地集合S2的子集subs2相等的话...那么就少了2个+操作...所以最后答案就是n1+n2-少掉的最多操作数, 由状压dp ...
- O - Matching 题解(状压dp)
题目链接 题目大意 给你一个方形矩阵mp,边长为n(n<=21) 有n个男生和女生,如果\(mp[i][j]=1\) 代表第i个男生可以和第j个女生配对 问有多少种两两配对的方式,使得所有男生和 ...
- [BZOJ 1879][SDOI 2009]Bill的挑战 题解(状压DP)
[BZOJ 1879][SDOI 2009]Bill的挑战 Description Solution 1.考虑状压的方式. 方案1:如果我们把每一个字符串压起来,用一个布尔数组表示与每一个字母的匹配关 ...
- BZOJ 3812 主旋律 (状压DP+容斥) + NOIP模拟赛 巨神兵(obelisk)(状压DP)
这道题跟另一道题很像,先看看那道题吧 巨神兵(obelisk) 题面 欧贝利斯克的巨神兵很喜欢有向图,有一天他找到了一张nnn个点mmm条边的有向图.欧贝利斯克认为一个没有环的有向图是优美的,请问这张 ...
- NOIP2017 宝藏 题解报告【状压dp】
题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏.但是 ...
- TZOJ 2289 Help Bob(状压DP)
描述 Bob loves Pizza but is always out of money. One day he reads in the newspapers that his favorite ...
- 【bzoj5161】最长上升子序列 状压dp+打表
题目描述 现在有一个长度为n的随机排列,求它的最长上升子序列长度的期望. 为了避免精度误差,你只需要输出答案模998244353的余数. 输入 输入只包含一个正整数n.N<=28 输出 输出只包 ...
- TZOJ 4912 炮兵阵地(状压dp)
描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P" ...
- POJ 1684 Corn Fields(状压dp)
描述 Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ ...
- 【uoj#37/bzoj3812】[清华集训2014]主旋律 状压dp+容斥原理
题目描述 求一张有向图的强连通生成子图的数目对 $10^9+7$ 取模的结果. 题解 状压dp+容斥原理 设 $f[i]$ 表示点集 $i$ 强连通生成子图的数目,容易想到使用总方案数 $2^{sum ...
随机推荐
- SQL中的多表查询,以及JOIN的顺序重要么?
说法是,一般来说,JOIN的顺序不重要,除非你要自己定制driving table. 示例: SELECT a.account_id, c.fed_id, e.fname, e.lname -> ...
- SQL中的JOIN类型解释(CROSS, INNER,OUTER),关键字ON,USING
书上讲得明白,解了不少迷惑. SELECT e.fname, e.lname, d.name FROM employee AS e INNER JOIN department AS d ON e.de ...
- 无废话ExtJs 入门教程十五[员工信息表Demo:AddUser]
无废话ExtJs 入门教程十五[员工信息表Demo:AddUser] extjs技术交流,欢迎加群(201926085) 前面我们共介绍过10种表单组件,这些组件是我们在开发过程中最经常用到的,所以一 ...
- Sql Server 索引之唯一索引和筛选索引
唯一索引(UNIQUE INDEX) 当主键创建时如果不设置为聚集索引,那么就一定是唯一的非聚集索引.实际上,唯一索引,故名思议就是它要求该列上的值是唯一的.唯一索引能够保证索引键中不包含重复的值, ...
- POJ3294 Life Forms(后缀数组)
引用罗穗骞论文中的话: 将n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组.然后二分答案,用和例3 同样的方法将后缀分成若干组,判断每组的后缀是否出现在不小于k 个的原串中 ...
- git revert 和 git reset的区别
git revert 撤销 某次操作,此次操作之前和之后的commit和history都会保留,并且把这次撤销 作为一次最新的提交 * git revert HEAD ...
- cmder
添加cmder到右键菜单 Cmder.exe /REGISTER ALL 打开配置快捷键 win+alt+p 文字重叠 main->font->去掉monospace的勾 λ符号修改 找到 ...
- 介绍n款计算机视觉库/人脸识别开源库/软件
计算机视觉库 OpenCV OpenCV是Intel®开源计算机视觉库.它由一系列 C 函数和少量 C++ 类构成,实现了图像处理和计算机视觉方面的很多通用算法. OpenCV 拥有包括 300 多个 ...
- orientation和gravity的区别
orientation:决定UI组件是按行还是列显示 gravity:指定文字对齐方式.
- php代码效率测试
对于一个被加载的页面,而遇到会卡的原因 ,代码量大,为了减少一句话分析,就采用分段式判断. 从php手册了解到,使用microtime函数,具体方法可参见php手册对这函数的用法 定义get_exec ...