题面

棋盘类状压 DP 经典题。

我们考虑设 \(dp_{i,j,s}\) 表示前 \(i\) 行已经摆了 \(j\) 个国王,且第 \(i\) 行国王摆放的状态为 \(s\) 的合法方案数。

转移的时候枚举每一行的每种状态及已经摆放了的国王数量,然后枚举上一行的状态,如果合法就更新。

但是这样做的时间复杂度大致是 \(10 \times 10^2 \times 2^{10} \times 10^3 = 10^9\) 的,明显会 TLE,于是我们考虑如何优化。

其实我们在转移时有很多不合法的状态,即转移时的无用状态。于是我们考虑预处理一下所有在转移时合法的状态,这样优化后我们就可以 AC 本题了。

#include <bits/stdc++.h>

using namespace std;

const int maxn = 13, maxm = 1 << 11, maxk = 103;

int n, m, k;
int cnt[maxm]; //存储每个状态中 1 的个数
long long ans, dp[maxn][maxk][maxm];
vector <int> g; //存储合法的状态
vector <int> can[maxm]; //存储每个状态可以转移到的合法状态 //判断一个状态是否合法,即判断是否有连续的 2 个 1
inline bool check(int x)
{
for (int i = 0; i < n; i+=1)
if ((x >> i & 1) && (x >> (i + 1) & 1))
return false;
return true;
} //求一个状态中 1 的个数
inline int get_1(int x)
{
int sum = 0;
for (int i = 0; i < n; i+=1)
if (x >> i & 1)
++sum;
return sum;
} int main()
{
cin >> n >> m;
for (int i = 0; i < (1 << n); i+=1) //枚举所有状态
if (check(i)) //该状态合法
{
g.push_back(i);
cnt[i] = get_1(i);
}
int len = g.size(); //合法状态的个数
for (int i = 0; i < len; i+=1)
for (int j = 0; j < len; j+=1) //枚举每两个合法的状态
{
int a = g[i], b = g[j];
if (!(a & b) && check(a | b))
can[i].push_back(j); //两个状态在转移时可以放相邻两行
}
dp[0][0][0] = 1;
for (int i = 1; i <= n; i+=1) //枚举行数
for (int j = 0; j <= m; j+=1) //枚举国王个数
for (int k = 0; k < len; k+=1) //枚举状态
{
int len1 = can[k].size(), geshu_1 = cnt[g[k]];
for (int ll = 0; ll < len1; ll+=1) //枚举上一行的状态
{
int l = g[can[k][ll]];
if (j >= geshu_1) //可以进行转移
dp[i][j][g[k]] += dp[i - 1][j - geshu_1][l];
}
}
for (int i = 0; i < (1 << n); i+=1) //枚举最后一行的状态
ans += dp[n][m][i]; //统计答案
cout << ans << endl; //输出答案
return 0;
}

题解【洛谷P1896】[SCOI2005]互不侵犯的更多相关文章

  1. 洛谷 P1896 [SCOI2005]互不侵犯

    洛谷 P1896 [SCOI2005]互不侵犯 题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8 ...

  2. 洛谷P1896 [SCOI2005]互不侵犯King

    P1896 [SCOI2005]互不侵犯King 题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共 ...

  3. 洛谷——P1896 [SCOI2005]互不侵犯

    P1896 [SCOI2005]互不侵犯 状压DP入门题 状压DP一般需要与处理状态是否合法,节省时间 设定状态dp[i][j][k]表示第i行第j个状态选择国王数为k的方案数 $dp[i][j][n ...

  4. 【题解】洛谷P1896 [SCOI2005] 互不侵犯(状压DP)

    洛谷P1896:https://www.luogu.org/problemnew/show/P1896 前言 这是一道状压DP的经典题 原来已经做过了 但是快要NOIP 复习一波 关于一些位运算的知识 ...

  5. 洛谷 P1896 [SCOI2005]互不侵犯 (状态压缩DP)

    题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 注:数据有加强(2018/4/25) ...

  6. 洛谷 P1896 [SCOI2005]互不侵犯King

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

  7. 洛谷P1896 [SCOI2005]互不侵犯King【状压DP】

    题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 输入格式: 只有一行,包含两个数N,K ...

  8. BZOJ1087=Codevs2451=洛谷P1896&P2326互不侵犯

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

  9. 【洛谷P1896】互不侵犯

    题目大意:给定 N*N 的棋盘,一共放 K 个国王,一共有多少种方法. 题解: i&i<<1 判断是否每个 1 的位置之间都有 0. i&j<<1 判断 i 中 ...

  10. P1896 [SCOI2005] 互不侵犯 方法记录

    原题链接 [SCOI2005] 互不侵犯 题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子 ...

随机推荐

  1. 学习分享--python网络爬虫(一)关于如何更新python pip以及如何安装python requests库

    一.python pip的更新(我的是window10 界面可能不太一样)    1.找到电脑左下角开始按钮,并点击: 2.输入cmd 3.打开以后,先查看自己的pip版本  输入:pip -V 敲回 ...

  2. jQuery--dataTable 前端分页与后端分页 及遇到的问题

    (1)区别 前端分页:一次性把所有数据全都放在前端,由前端进行处理:适合请求的数据量不大的情况 后端分页:服务器模式,所有的分页,搜索,排序等操作在服务器端完成,然后前端去请求数据:适合量大的情况 ( ...

  3. StackExchange.Redis 之 String 类型示例

    String类型很简单,就不做示例演示了,这里只贴出Helper类 /// <summary> /// 判断key是否存在 /// </summary> /// <par ...

  4. StarUML之三、StarUML的项目

    1:创建空的项目 创建项目可以按Ctrl+N或选择菜单File| New,StarUML安装打开后默认会有个空项目结构. 2:创建模板项目 可以通过选择模板来启动建模项目(会根据模板创建项目结构). ...

  5. Android Gradle报错 (Error:No such property: GradleVersion for class: JetGradlePlugin) 的原因与解决

    Error:No such property: GradleVersion for class: JetGradlePlugin 错误原因:IDE 版本(GradlePlugin)和 Gradle 版 ...

  6. luogu P3369 【模板】普通平衡树

    ————————————————版权声明:本文为CSDN博主「ModestCoder_」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明.原文链接:https:// ...

  7. 实验一Git代码版本管理

    GIT代码版本管理 实验目的: 1)了解分布式分布式版本控制系统的核心机理: 2) 熟练掌握git的基本指令和分支管理指令: 实验内容: 1)安装git 2)初始配置git ,git init git ...

  8. 自然语言处理(1)-HMM隐马尔科夫模型基础概念(一)

    隐马尔科夫模型HMM 序言 文本序列标注是自然语言处理中非常重要的一环,我先接触到的是CRF(条件随机场模型)用于解决相关问题,因此希望能够对CRF有一个全面的理解,但是由于在学习过程中发现一个算法像 ...

  9. Scout YYF I POJ - 3744【矩阵乘法优化求概率】

    题意: 一条路上有 $n$ 个地雷,YYF 从位置 $1$ 出发,走一步的概率为 $p$,走两步的概率是 $(1-p)$.求 YYF 能顺利通过这条路的概率. 数据范围: $1\leq n \leq ...

  10. ES的性能优化

    ES的性能优化 es在数据量很大的情况下(数十亿级别)如何提高查询效率? 在es里,不要期待着随手调一个参数,就可以万能的应对所有的性能慢的场景.也许有的场景是你换个参数,或者调整一下语法,就可以搞定 ...