互不侵犯king (状压dp)

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

  这道题如果普通dfs肯定会超时。为什么呢?我们发现一行中的状态是固定的,同时行与行之间的冲突情况也是固定的。而dfs重复枚举了每一行的状态,重复判断了这一行的状态是否与前一行相冲突。于是我们预处理出一行中的状态,同时预处理出两行状态的冲突情况,然后dp就行了。\(f[i][j][k]\)表示枚举到第i行,有j个国王,当前行状态的编号为k。它只能通过不与k冲突的上一行转移而来。于是就过了。

#include <cstdio>
using namespace std; long long st[100];
int cnt[100], now[10], map[100][100];
int n, k, cntst;
long long f[10][100][100]; void dfs(int pos){
now[pos]=1;
long long tmp=0; ++cntst;
for (int i=1; i<=n; ++i){
tmp=(tmp<<1)+now[i];
cnt[cntst]+=now[i];
}
st[cntst]=tmp;
for (int i=pos+2; i<=n; ++i) dfs(i);
now[pos]=0;
} int main(){
scanf("%d%d", &n, &k);
st[0]=0; cnt[0]=0;
for (int i=1; i<=n; ++i) dfs(i);
for (int i=0; i<=cntst; ++i)
for (int j=0; j<=cntst; ++j)
if ((st[i]&st[j])==0&&
((st[i]<<1)&st[j])==0&&
((st[i]>>1)&st[j])==0){
map[i][j]=1; map[j][i]=1;
}
f[0][0][0]=1;
for (int i=1; i<=n; ++i)
for (int j=0; j<=k; ++j)
for (int st=0; st<=cntst; ++st){
if (cnt[st]>j) continue;
for (int st2=0; st2<=cntst; ++st2){
if (!map[st][st2]) continue;
f[i][j][st]+=f[i-1][j-cnt[st]][st2];
}
}
long long ans=0;
for (int i=0; i<=cntst; ++i)
ans+=f[n][k][i];
printf("%lld", ans);
return 0;
}

互不侵犯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 互不侵犯King 状压DP+DFS预处理

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

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

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

  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. BZOJ 1087 [SCOI2005]互不侵犯King ——状压DP

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

  7. bzoj1087互不侵犯King——状压DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1087 水题... 然而犯了两个致命小错误,调了好半天...详见注释. 代码如下: #incl ...

  8. 互不侵犯_状压$dp$

    如果有想学习状压\(dp\)的童鞋,请光临博客状压\(dp\)初学 互不侵犯 题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八 ...

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

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

随机推荐

  1. 分享知识-快乐自己:java代码 操作 solr

    POM 文件: <!-- solr客户端 --> <dependency> <groupId>org.apache.solr</groupId> < ...

  2. 一个用 vue 写的树层级组件 vue-ztree

    最近看了大神的关于vue-ztree的博客,感觉很赞,于是摘抄下来,方便自己学习,机智girl,哈哈哈O(∩_∩)O 最近由于后台管理项目的需要,页面需要制作一个无限树的需求,我第一感就想到了插件 z ...

  3. COM组件的集合与包容

    集合与包容,实质就是组件之间的互相调用.即一个组件使用另一个组件的功能,达到代码复用的作用.只是这种复用是构建在二进制数据上的(因为被复用的组件常常以dll的格式存在),而不是像c++代码复用是以源文 ...

  4. os.path

  5. Gym - 100801G: Graph (贪心+set+拓扑)(好题)

    题意:给定一个N点M边的有向图,叫你加最多K条边,使得最小拓扑序最大. 思路:不是那么简单的题.  参照了别人的代码, 最后想通了. 贪心原则: 用两个单调队列维护, 第一个序列S1单增, 表示当前入 ...

  6. 浅谈MVC、MVP、MVVM模式

    mvc的模式已经深入人心,想必大家都很熟悉,但是未必都能遵守mvc模式.我们的一个mvc项目比较简单,主要是数据库的查询.一个DBHelp类,封装了数据库的操作,然后Controller中进行中各种查 ...

  7. Java中String和byte[]间的 转换

    数据库的字段中使用了blob类型时,在entity中此字段可以对应为byte[] 类型,保存到数据库中时需要把传入的参数转为byte[]类型,读取的时候再通过将byte[]类型转换为String类型. ...

  8. C++11中的原子操作(atomic operation)

    所谓的原子操作,取的就是“原子是最小的.不可分割的最小个体”的意义,它表示在多个线程访问同一个全局资源的时候,能够确保所有其他的线程都不在同一时间内访问相同的资源.也就是他确保了在同一时刻只有唯一的线 ...

  9. 对象流demo1----

    对象流demo1: package com.etc.test; import java.io.BufferedInputStream; import java.io.BufferedOutputStr ...

  10. hibernate 数据关联一对多

    一对多,多对一 (在多的一端存放一的外键) 但是在实体类中不需要创建这个外键 // 在一的一方创建Set集合 public class User { private Integer id; priva ...