1087: [SCOI2005]互不侵犯King

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 4130  Solved: 2390
[Submit][Status][Discuss]

Description

  在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上
左下右上右下八个方向上附近的各一个格子,共8个格子。

Input

  只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)

Output

  方案数。

Sample Input

3 2

Sample Output

16
一开始看做和八皇后类似的打表,后来发现攻击范围和八皇后的并不同而且这道题目要求了必须放入指定数目的"国王"
数据范围并不是很大,标准的棋盘模型很容易联想到状压dp,关键就是切入点,用轮廓线的话不怎么好写,不妨逐行递推,我们用1表示这个格子放入了国王,
从上往下递推所以不必考虑下面的国王对上面的有影响,这样的状态是非法的,注意到dp时多次用到状态之间的关系,考虑提前打表节约时间。
由于限制了棋子的数目,相应的也要多加一维用于表示棋子数目,则显然  dp[i][j][k]+=dp[i-1][j-cnt[B]][A] ;
dp[i][j][k]表示第i行状态为k,总共放置了j个棋子时的方案个数。
复杂度O(N*M*2n*2n)  N<=9,复杂度合适
 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define LL long long
LL dp[][][<<],cnt[];
bool e[][],q[];
int N,M;
bool pd(int A,int B)
{
bool hurt[]; memset(hurt,,sizeof(hurt));
for(int i=;i<;++i)
if(A&(<<i)) hurt[i++]=hurt[i-+]=hurt[i+]=;
for(int i=;i<;++i)
if( (B&(<<i)) && hurt[i+]) return ;
return ;
}
void pre()
{
for(int i=;i<(<<);++i){ int ss=;
for(int j=;j<;++j) if(i&(<<j)) ss++;
cnt[i]=ss;
}
for(int i=;i<(<<);++i){int ok=;
for(int j=;j<;++j){
if((i&(<<j))&&(i&(<<(j+)))){ok=;break;}
}
q[i]=ok;
}
for(int i=;i<(<<);++i){
for(int j=;j<(<<);++j){
if((!q[i])||(!q[j])) {e[i][j]=;}
else {
if(pd(i,j)) {e[i][j]=; }
}
}
}
}
int main()
{
pre();
int i,j,k;
scanf("%d%d",&N,&M);
dp[][][]=;
for(i=;i<=N;++i)
{
for(k=;k<=M;++k)
{
for(int A=;A<(<<N);++A){
for(int B=;B<(<<N);++B){
if(e[A][B]&&k-cnt[B]>=){
dp[i][k][B]+=dp[i-][k-cnt[B]][A];
}
}
}
}
}LL ans=;
for(i=;i<(<<N);++i) ans+=dp[N][M][i];
printf("%lld\n",ans);
return ;
}

bzoj 1087 状压dp的更多相关文章

  1. bzoj 1879 状压dp

    879: [Sdoi2009]Bill的挑战 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 852  Solved: 435[Submit][Status ...

  2. BZOJ 2064 - 状压DP

    传送门 题目大意: 给两个数组, 数组中的两个元素可以合并成两元素之和,每个元素都可以分裂成相应的大小,问从数组1变化到数组2至少需要多少步? 题目分析: 看到数据范围\(n<=10\), 显然 ...

  3. BZOJ 4057 状压DP

    思路: 状压一下 就完了... f[i]表示选了的集合为i 转移的时候判一判就好了.. //By SiriusRen #include <cstdio> #include <cstr ...

  4. BZOJ 4565 状压DP

    思路: f[i][j][S]表示从i到j压成S状态 j-m是k-1的倍数 $f[i][j][S<<1]=max(f[i][j][S<<1],f[i][m-1][S]+f[m][ ...

  5. bzoj 1072状压DP

    1072: [SCOI2007]排列perm Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2293  Solved: 1448[Submit][St ...

  6. bzoj 1072 状压DP

    我们用w[i][j]来表示,i是一个二进制表示我们选取了s中的某些位,j表示这些位%d为j,w[i][j]则表示这样情况下的方案数,那么我们可以得到转移.w[i|(1<<k)][(j*10 ...

  7. bzoj 2669 状压DP

    因为最多有8个'X',所以我们可以用w[i][s]来表示现在我们填了前i个数,填的X的为S,因为每次新加进来的数都不影响前面的最小值,所以我们可以随便添加,这样就有了剩下所有位置的方案,每次都这样转移 ...

  8. bzoj 1076 状压DP

    我们设w[i][s]为当前到第i关,手中的物品为s的时候,期望得分为多少,其中s为二进制表示每种物品是否存在. 那么就比较容易转移了w[i][s]=(w[i-1][s']+v[j]) *(1/k),其 ...

  9. BZOJ 1231 状压DP

    思路: f[i][j] i表示集合的组成 j表示选最后一个数 f[i][j]表示能选的方案数 f[i|(1<< k)][k]+=f[i][j]; k不属于i j属于i且符合题意 最后Σf[ ...

随机推荐

  1. python16_day26【crm 增、改、查】

    一.增加 二.修改 三.保存

  2. android上传图片、视频、文件,服务端使用wcf接收

    最近一直在搞android上传图片.视频.文件,服务端使用wcf接收,本文对调试中的遇到的问题进行记录. 首先android上传一些小图片是比较容易的一天下来差不多就能调试出来,但是上传一些大的文件时 ...

  3. hash值是啥,单页面应用的实质

    1.什么hash Location hash属性,http://www.runoob.com/jsref/prop-loc-hash.html,hash 属性是一个可读可写的字符串,该字符串是 URL ...

  4. 端口状态说明 LISTENING、ESTABLISHED、TIME_WAIT及CLOSE_WAIT

    TCP状态转移要点    TCP协议规定,对于已经建立的连接,网络双方要进行四次握手才能成功断开连接,如果缺少了其中某个步骤,将会使连接处于假死状态,连接本身占用的资源不会被释放.网络服务器程序要同时 ...

  5. Openwrt架设GIT服务

    #下载宝刷LEDE版系统后, 在上面安装git包 opkg update opkg install git #安装好后在将git仓库装到SD(TF)卡上 #用fdisk对SD 卡分区 #fdisk / ...

  6. PHP(Mysql/Redis)消息队列的介绍及应用场景案例

    在进行网站设计的时候,有时候会遇到给用户大量发送短信,或者订单系统有大量的日志需要记录,还有做秒杀设计的时候,服务器无法承受这种瞬间的压力,无法正常处理,咱们怎么才能保证系统正常有效的运行呢?这时候我 ...

  7. Eclipse安装Activiti插件(流程设计器)

    Eclipse安装Activiti插件(流程设计器) 一.安装步骤: 1,打开Eclipse的 Help -> Install New Software,填上插件地址: Name:Activit ...

  8. 20145216 史婧瑶《Java程序设计》第6周学习总结

    20145216 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 输入/输出 10.1 InputStream与OutputStream 如果要将数据从来源中取出,可以使用输 ...

  9. 20145303刘俊谦 Java 代码托管

    (20145303刘俊谦) Java 第三周代码托管 这是最近保存下来的代码,今天一起上传的,有很多在代码学习过程中无意识删掉了:

  10. [BZOJ4756]Promotion Counting

    Description The cows have once again tried to form a startup company, failing to remember from past ...