题面

棋盘类状压 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;
}

最新文章

  1. Logstash实践: 分布式系统的日志监控
  2. C/C++ 笔试题
  3. 汇编语言写出的helloworld运行过程
  4. IIS------IIS上部署MVC网站,打开后ExtensionlessUrlHandler-Integrated-4.0解决办法
  5. IOS- 堆和栈 详解
  6. log4net 日志框架的配置
  7. IE浏览器部分版本不支持opacity透明度属性问题
  8. appium初探问题总结
  9. Java基础知识强化37:StringBuffer类之StringBuffer的构造方法
  10. 爬虫总结_python
  11. 修改AD FS
  12. python全栈开发day51-jquery插件、@media媒体查询、移动端单位、Bootstrap框架
  13. 面向连接的tcp 编程
  14. C#语言不常用语法笔记
  15. Linux(CentOS)上配置 SFTP(附解决Write failed: Broken pipe Couldn&#39;t read packet: Connection reset by peer)
  16. es6generator
  17. Springboot2.x 集成redis
  18. 学习magento要学哪些知识
  19. Openstack(三)Haproxy+Keepalived双机
  20. Python数据生成pdf文件

热门文章

  1. npm/gulp/nodejs
  2. 复杂系统架构设计&lt;1&gt;
  3. 谈谈:这次疫情对一个普通iOS开发者的影响!
  4. 微信小程序入门笔记-开通云开发(3)
  5. 数据库 left()、length()函数
  6. MySQL基础篇(02):从五个维度出发,审视表结构设计
  7. jquery.datetimepicker中报错Cannot read property &#39;top&#39; of undefined
  8. 修改Ubuntu的apt-get源为国内镜像源的方法
  9. MySQL基础篇(01):经典实用查询案例,总结整理
  10. 备战2020年金三银四,看这一篇面试文章就够了(合适各级Java人员)