博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
状压DP
阅读量:5168 次
发布时间:2019-06-13

本文共 910 字,大约阅读时间需要 3 分钟。

状态压缩是设计dp状态的一种方式。

当普通的dp状态维数很多(或者说维数与输入数据有关),但每一维总量很少时,可以将多维状态压缩为一维来记录。

这种题目最明显的特征就是:都存在某一给定信息的范围非常小(在20以内),而我们在dp中所谓压缩的就是这一信息。

(或者是在做题过程中分析出了某一信息种类数很少)

我们来看个例子。

 

经典题

给出一个n*m的棋盘,要放上一些棋子,要求不能有任意两个棋子相邻。求方案数。

n<=100;

m<=8。

 

如果m固定的话可以设f[i][0/1][0/1]...[0/1]表示每一行每一列放不放

如果不是固定的呢?

我们发现后面的多个0/1可以看成一个二进制数

那我们不就可以用数字代替后面的维数吗?

f[i][s]->f[i+1][s’](s&s’==0)

 

你会发现这样记录很暴力,状态数是与m相关的指数级的,但同时也就是因为m小我们就确实可以这么做。

 

其实本质就是很暴力的记录状态,只不过利用了题目本身的特殊条件(这一维很小),使得我们并不会因此复杂度过高。

同时也就是说,如果题目本身没有这样一个较小的信息,就不能应用状态压缩。

状态压缩dp肯定是有一维是指数级的,这正是状态压缩的特点。

来看一道题:

P1896 [SCOI2005]互不侵犯

                  

 

  

 

这个题可以状压DP的很明显的标志就是数据范围

我们设f[i][j][k]表示当前在第i行,这一行及之前总共放了j个国王,当前的状态是k

那么我们只要枚举行,然后再枚举状态转移就可以了

怎么判断互不侵犯?

用位运算就可以了

注意最后答案不能光统计最后一行,因为不一定在最后一行才用完所有的国王

代码:

#include
using namespace std;typedef long long ll;int n,king;ll f[10][100][2000];int s[2000],num[2000];int cnt;ll ans;inline void pre(){ int tot=(1<

 

转载于:https://www.cnblogs.com/lcezych/p/11460484.html

你可能感兴趣的文章
ES6学习之Symbol
查看>>
Bedrock Linux 0.7.3 发布
查看>>
html3
查看>>
iOS - Bluetooth 蓝牙
查看>>
POJ2749 Building roads
查看>>
查看sql语句执行时间/测试sql语句性能
查看>>
java利用正则截取字符串中的数字
查看>>
redis的安装与使用
查看>>
vue - webpack.dev.conf.js
查看>>
HTML+CSS 工作笔记
查看>>
Windows Server 2008 64 位 IIS7.5 ASP.NET 发布问题
查看>>
spring简介(个人笔记)
查看>>
《我是一只IT小小鸟》读书笔记
查看>>
poj1163The Triangle(简单DP)
查看>>
vb.net 参考-关键字,常量,数据类型,
查看>>
这次要好好吐槽下idea呢还是SpringMVC ?
查看>>
【转】NoSQL初探之人人都爱Redis:(2)Redis API与常用数据类型简介
查看>>
Excel催化剂开源第23波-VSTO开发辅助录入功能关键技术
查看>>
python 列表,元祖,字典
查看>>
秦曾昌人工智能课程---1、机器学习中的数学基础
查看>>