【题目大意】

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

【思路】

先预处理每一行可行的状态(即单行中左右没有相邻的1),存放到usable中。

然后预处理usable中两两之间能否相互转换,存放到map中。

f[i][j][k]第i行,已用去j个国王,当前行状态为usable[k]的情况,四重循环暴力递推即可!

这里用了usable按道理应该会快一些,但是和popoqqq的速度是一样的?不过这个优化应该是有效的!

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN=;
const int MAXK=;
const int MAXM=;
int n,m;
int map[MAXN][MAXN];
ll f[MAXM][MAXK][MAXN];//f[i][j][k]第i行,已用去j个国王,当前行状态为k
int usable[MAXN];
int digit[MAXN]; int Usable(int x)
{
if (x<<&x || x>>&x) return ;else return ;
//不能有相邻的1
} int get_digit(int x)
{
int ret=;
while (x) ret+=x&,x>>=;
return ret;
} int Judge(int x,int y)
{
if (x&y || (x<<)&y || (x>>)&y) return ;else return ;
/*不可行的情况有三种*/
} void init()
{
memset(usable,,sizeof(usable));
memset(map,,sizeof(map));
for (int i=;i<<<n;i++)
if (Usable(i)) usable[++usable[]]=i;
/*预处理可行的状态(左右不能有相邻的1)*/
for (int i=;i<=usable[];i++)
for (int j=;j<=usable[];j++)
{
if (Judge(usable[i],usable[j])) map[i][j]=;
}
/*预处理可行的状态中能够转换的状态*/
for (int i=;i<=usable[];i++) digit[i]=get_digit(usable[i]);
/*预处理每一个可行状态中1的个数*/
} ll dp()
{
memset(f,,sizeof(f));
f[][][]=;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
for (int k=;k<=usable[];k++)
if (digit[k]<=j)
{
for (int l=;l<=usable[];l++)
{
if (map[l][k] && digit[l]+digit[k]<=j)
f[i][j][k]+=f[i-][j-digit[k]][l];
}
}
ll ret=;
for (int i=;i<=usable[];i++) ret+=f[n][m][i];
return ret;
} int main()
{
scanf("%d%d",&n,&m);
init();
cout<<dp()<<endl;
return ;
}

【状态压缩DP】BZOJ1087-[SCOI2005]互不侵犯King的更多相关文章

  1. BZOJ1087 SCOI2005 互不侵犯King 【状压DP】

    BZOJ1087 SCOI2005 互不侵犯King Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附 ...

  2. 状压入门--bzoj1087: [SCOI2005]互不侵犯King【状压dp】

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

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

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

  4. bzoj1087: [SCOI2005]互不侵犯King (codevs2451) 状压dp

    唔...今天学了状压就练练手... 点我看题 这题的话,我感觉算是入门题了QAQ... 然而我还是想了好久... 大致自己推出了方程,但是一直挂,调了很久选择了题解 坚持不懈的努力的调代码. 然后发现 ...

  5. [bzoj1087][scoi2005]互不侵犯king

    题目大意 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上 左下右上右下八个方向上附近的各一个格子,共8个格子. 思路 首先,搜索可以放弃,因为这是一 ...

  6. BZOJ1087 [SCOI2005]互不侵犯King 状态压缩动态规划

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1087 题意概括 在n*n的棋盘上面放k个国王,使得他们互相无法攻击,问有多少种摆法. 题解 dp[ ...

  7. [BZOJ1087][SCOI2005]互不侵犯King解题报告|状压DP

    在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 好像若干月前非常Naive地去写过DFS... ...

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

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

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

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

随机推荐

  1. HDU 2126 01背包(求方案数)

    Buy the souvenirs Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  2. codeforces 1015B

    B. Obtaining the String time limit per test 1 second memory limit per test 256 megabytes input stand ...

  3. 买卖股票的最佳时机 [ leetcode ]

    原题地址:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/description/ 给定一个数组,它的第 i 个 ...

  4. jw player学习笔记----跨域请求

    需求来源:播放器皮肤文件请求不到,被限制了. 参考官网解决方案: http://www.longtailvideo.com/support/jw-player/28844/crossdomain-fi ...

  5. Spring学习--引用其他Bean , 内部Bean

    引用其他Bean: 组成应用程序的 Bean 经常需要相互协作以完成应用程序的功能 , 要使 Bean 能够相互访问, 就必须在 Bean 配置文件中指定对 Bean 的引用. 在 Bean 的配置文 ...

  6. MAC电脑密码破解

    [第一个方法] 开机,启动时按cmd+S,进入Single User Mode,出现像DOS一样的提示符#root> 在#root>下输入(注意空格,大小写)   fsck -y moun ...

  7. 【Foreign】开锁 [概率DP]

    开锁 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output Sample Input 4 5 1 2 5 4 3 1 5 ...

  8. 【BZOJ】[SDOI2009]HH的项链

    [算法]主席树||离线+树状数组 [题解] 主席树经典应用:找区间不同的数字个数. 做法:记录每个数上一次出现的位置last[i],对last建权值线段树,对于区间询问last[i]<L的数字个 ...

  9. BZOJ1003: [ZJOI2006] 物流运输 trans

    物流运输--看了神犇的题解,就是dp+最短路,设f[i]为1~i天的最少花费,那么 dp[i]=min(cost[1,i],min{dp[j]+cost[j+1,i]+K,1≤j<i}) 就是从 ...

  10. js一段小代码(浏览器用alert,否则用console)

    (function(){ var root=this, isBrowserSide=false; if(typeof window !=="undefined" && ...