码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj1087[SCOI2005]互不侵犯King

时间:2016-07-21 21:40:40      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:

bzoj1087[SCOI2005]互不侵犯King

题意:

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

题解:

状压dp。我的做法是像插头dp那样保存当前列右侧的上一行和当前列左侧的当前行的情况,同时加一列存左上角的状态,逐格递推,滚动掉行列的状态表示。过倒是过了然而是状态版上的倒数第一。我状压dp递推的时候不知道怎么省状态,可能写记忆化搜索会快一些,但就不能滚动了。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define inc(i,j,k) for(int i=j;i<=k;i++)
 5 using namespace std;
 6 
 7 long long x[100][10000],y[100][10000],n,k;
 8 inline bool bit(int x,int y){return x&(1<<(y-1));}
 9 inline int set(int x,int y,bool z){
10     if(z)return x|(1<<(y-1));else return x&((1<<(n+1))-1-(1<<(y-1)));
11 }
12 int main(){
13     scanf("%d%d",&n,&k); x[k][0]=1;
14     inc(i1,1,n)inc(j1,1,n){
15         inc(i2,0,k)inc(j2,0,(1<<(n+1))-1)y[i2][j2]=0;
16         inc(i2,0,k)inc(j2,0,(1<<(n+1))-1){
17             if(i2&&(j1==1||(! bit(j2,j1-1)))&&(i1==1||(! bit(j2,j1)))&&(i1==1||j1==1||(! bit(j2,n+1)))&&(j1==n||(! bit(j2,j1+1))))
18                 y[i2-1][set(set(j2,n+1,bit(j2,j1)),j1,1)]+=x[i2][j2];
19             y[i2][set(set(j2,n+1,bit(j2,j1)),j1,0)]+=x[i2][j2];
20         }swap(x,y);
21     }
22     long long ans=0; inc(i,0,(1<<(n+1))-1)ans+=x[0][i]; printf("%lld",ans);
23     return 0;
24 }

 

20160329

bzoj1087[SCOI2005]互不侵犯King

标签:

原文地址:http://www.cnblogs.com/YuanZiming/p/5692990.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!