[SCOI2005]互不侵犯King

【题目描述】

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

【输入】

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

【输出】

方案数。

【样例输入】

3 2

【样例输出】

16

分析:

经典的状压DP题目,可我竟然调了很长时间都没对,后来发现是DP枚举范围错了,直接枚举到最大情况导致答案大得离谱,所以透彻理解算法很重要。

其它懒得写了。

代码1(第一次写的代码很丑,还很多余地在每个二进制首位增添一个1......):

program king;
var
f:array[..,..,..]of int64;
a:array[..,..]of ..;
sum1,w:array[..]of longint;
g:array[..,..]of boolean;
h:array[..]of boolean;
n,i,m,j,k,u,v,l,num,num1:longint;
procedure work(x:longint);
var i,c,y:longint;
begin
i:=x; c:=;
while i> do
begin
a[x,c]:=i mod ; if a[x,c]= then begin inc(sum1[x]); if c> then y:=-c+; end;
i:=i div ;
c:=c-;
end;
dec(sum1[x]); w[x]:=y;
end;
begin
readln(n,k);num1:=;num:=;
for i:= to n do num:=num*;
num:=num1+num-;
for i:=num1 to num do
begin
work(i);
end;
for u:=num1 to num do
for v:=num1 to num do
for l:= to do begin g[u,v]:=true;
if (a[u,l]=)and(((a[v,l-]=)and(l>))or(a[v,l]=)or(a[v,l+]=)) then begin g[u,v]:=false;break; end;
if (a[v,l]=)and(((a[u,l-]=)and(l>))or(a[u,l]=)or(a[u,l+]=)) then begin g[u,v]:=false;break; end;
end;
fillchar(f,sizeof(f),);
for i:=num1 to num do begin h[i]:=true;
for j:= to do
if ((a[i,j]=)and(((a[i,j-]=)and(j>))or(a[i,j+]=))) then begin h[i]:=false; break; end;
if h[i]=true then f[,i,sum1[i]]:=;
end;
for i:= to n+ do
for j:= to k do
for u:=num1 to num do
if (sum1[u]<=j)and(h[u]=true) then
for v:=num1 to num do
if (sum1[v]+sum1[u]<=j)and(h[v]=true) then
begin
if g[u,v]=true then f[i,u,j]:=f[i,u,j]+f[i-,v,j-sum1[u]];
end;
writeln(f[n+,num1,k]);
end.

代码2(改进的代码,用了一些位运算,比第一次好看一点):

program king;
var
f:array[..,..,..]of int64;
sum1:array[..]of longint;
g:array[..,..]of boolean;
h:array[..]of boolean;
n,i,m,j,k,u,v,l,t,num:longint;
begin
readln(n,k);
fillchar(g,sizeof(g),false);
fillchar(h,sizeof(h),false);
fillchar(f,sizeof(f),);
num:=;
for i:= to n do num:=num*; num:=num-;
for i:= to num do
if i and (i shr )= then
begin
j:=i;t:=;
while j> do begin t:=t+j and ; j:=j shr ; end;
sum1[i]:=t; h[i]:=true;
end;
for i:= to num do if h[i]=true then
for j:= to num do if h[j]=true then
if (i and j=)and(i and (j shr )=)and(j and (i shr )=) then g[i,j]:=true;
for i:= to num do if h[i]=true then f[,i,sum1[i]]:=;
for i:= to n+ do
for j:= to k do
for u:= to num do if (h[u]=true)and(sum1[u]<=j) then
for v:= to num do if (h[v]=true)and(sum1[u]+sum1[v]<=j) then
if g[v,u]=true then
inc(f[i,u,j],f[i-,v,j-sum1[u]]);
writeln(f[n+,,k]);
end.

BZOJ 1087:[SCOI2005]互不侵犯King(状压DP)的更多相关文章

  1. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  2. BZOJ 1087 [SCOI2005]互不侵犯King ——状压DP

    [题目分析] 沉迷水题,吃枣药丸. [代码] #include <cstdio> #include <cstring> #include <iostream> #i ...

  3. bzoj 1087 [SCOI2005]互不侵犯King 状态压缩dp

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MB[Submit][Status][Discuss] Descripti ...

  4. 【BZOJ1087】 [SCOI2005]互不侵犯King 状压DP

    经典状压DP. f[i][j][k]=sum(f[i-1][j-cnt[k]][k]); cnt[i]放置情况为i时的国王数量 前I行放置情况为k时国王数量为J #include <iostre ...

  5. [BZOJ1087] [SCOI2005] 互不侵犯King (状压dp)

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

  6. 互不侵犯king (状压dp)

    互不侵犯king (状压dp) 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子.\(1\le n\ ...

  7. BZOJ-1087 互不侵犯King 状压DP+DFS预处理

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2337 Solved: 1366 [Submit][ ...

  8. bzoj1087 互不侵犯King 状压dp+bitset

    题目传送门 题目大意:中文题面. 思路:又是格子,n又只有9,所以肯定是状压dp,很明显上面一行的摆放位置会影响下一行,所以先预处理出怎样的二进制摆放法可以放在上下相邻的两行,这里推荐使用bitset ...

  9. BZOJ 1087 [SCOI2005]互不侵犯King(状压DP)

    题意:在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子.n<=9 思路:状压dp,dp[i][ ...

  10. [SCOI2005]互不侵犯(状压DP)

    嗝~算是状压DP的经典题了~ #\(\mathcal{\color{red}{Description}}\) 在\(N×N\)的棋盘里面放\(K\)个国王,使他们互不攻击,共有多少种摆放方案.国王能攻 ...

随机推荐

  1. geoNear查询 near查询的升级版

    geoNear查询可以看作是near查询点进化版 geoNear查询使用runCommand命令进行使用,常用使用如下: db.runCommand({ geoNear:<collection& ...

  2. Python实现购物小程序

    一.需求 1.登录 { ‘xxx1’:{'passwd':'123','role':1,'moeny':10000,"carts":['mac']}, 'xxx1':{'passw ...

  3. 企业shell面试题及解答

    1.面试题:使用for循环在/tmp目录下批量创建10个html文件,其中每个文件需要包含10个随机小写字母加固定字符串template,示例如下 aaesdffbnv_template.html 方 ...

  4. 【Ecshop】修改处理用户购物车的行为

    Ecshop v2.7.3的购物车处理方面在现在看来有比较反用户体验的设计: 用户未登录时加入购物车的商品,在用户登录后会被清空而不是加入到登录用户的购物车中: 用户登录后加入购物车的商品,在退出后会 ...

  5. WebUploader压缩图片上传

    WebUploader,由Baidu FEX 团队开发,以H5为主,FLASH为辅,兼容 IE6+,iOS 6+, android 4+,采用大文件分片并发上传,极大的提高了文件上传效率,看了官方文档 ...

  6. 06.VUE学习之非常实用的计算属性computed实例

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  7. Java中的接口和抽象类(转)

    在面向对象的概念中,我们知道所有的对象都是通过类来描述的,但是并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 抽象类往往用来表征我们在对问题 ...

  8. stark组件前戏(1)之项目启动前加载指定文件

    django项目启动时,可以自定义执行某个py文件,这需要在任意app的apps.py中的Config类定义ready方法,并调用.   from django.apps import AppConf ...

  9. 饭卡 HDU - 2546(dp)

    电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额.如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够).所以大家 ...

  10. [Poj3281]Dining(最大流)

    Description 有n头牛,f种食物,d种饮料,每头牛有nf种喜欢的食物,nd种喜欢的饮料,每种食物如果给一头牛吃了,那么另一个牛就不能吃这种食物了,饮料也同理,问最多有多少头牛可以吃到它喜欢的 ...