AcWing - 闫氏DP分析法
核心思想:从集合角度来分析DP问题
在我们遇到的DP问题中,一般都是求在一个有限集内的最值,但是这些方案数量一般都是指数级别的,想要一个一个查找出来不太可能。所以DP方法是用来优化这种寻找最优方案的过程的。
DP问题一般来说分析时都要经过两个阶段:
状态表示(化零为整):指把一些具有相似点的方案,划分为一个子集,然后用一个状态来表示它。现在假设我们的状态表示为 \(f[i]\)。
状态表示要从两个角度来分析:
- 集合:\(f[i]\) 表示的集合就是:所有满足xxx条件的集合。正是因为我们的 \(f[i]\) 可以表示一类东西而不是一个东西,这样就可以达到优化的作用。
- 属性:也就是我们状态存的这个值是这个集合的什么东西,也就是最大值/最小值/数量等等。
状态计算(化整为零):先看一下 \(f[i]\) 表示的所有状态是什么:
比如说是这个集合:

然后把它划分成一个个子集(如果求的是数量那么必须不重复;如果求的是最大值就不用管了),我们的划分依据是:寻找最后一个不同点。

如果要求整个状态的最大值的话,我们只需要把这个状态的所有子集的最大值求出来,再把整个集合的最大值求出来就可以了。这样,我们就成功把一个大问题分解成一个个小问题求解出来了。
举例:01背包问题

开始使用闫氏DP分析法!
状态表示:\(f[i][j]\)
- 集合:所有只考虑前 \(i\) 个物品,且总体积不超过 \(j\) 的选法的集合。
- 属性:Max(最大值)
状态计算:

想要取得最大值,只需要得出左边集合的最大值和右边集合的最大值就可以了。
我们来看一下这两个子集分别是什么

完成!这样我们就成功地把这个问题推出来了。
这个问题还可以再继续优化,目前的状态表示是二维的,但是每次我们只会用到第 \(i - 1\) 层的东西,这样就可以用滚动数组来优化了。还有,我们的状态表示的第二维要么是用自己,要么是用比自己小的数,我们就可以从大到小枚举体积,换为一维数组来存储状态。
为什么可以这样呢?如果用一维数组来存储状态,状态转移方程就是这样了:
\(f[j] = max(f[j], f[j - v[i]] +w[i])\)
因为我们是从大到小枚举体积,所以这时的 \(f[j - v[i]]\) 还没有在第 \(i\) 层被更新过;所以此时它存的就是上一层的 \(f[j - v[i]]\),也就是 \(f[i - 1][j - v[i]]\)。
代码:
朴素版
#include <iostream>
#define N 1010
using namespace std;
int n, m;
int v[N], w[N];
int f[N][N];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; ++i) cin >> v[i] >> w[i];
for (int i = 1; i <= n; ++i)
for (int j = 0; j <= m; ++j) {
f[i][j] = f[i - 1][j]; // 左半边的子集
if (j >= v[i]/*右半边的方案是存在的*/) f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);
}
cout << f[n][m] << '\n';
return 0;
}
优化版
#include <iostream>
#define N 1010
using namespace std;
int n, m;
int v[N], w[N];
int f[N];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; ++i) cin >> v[i] >> w[i];
for (int i = 1; i <= n; ++i)
for (int j = m; j >= v[i]/*就相当于在循环里判断一句j >= v[i]*/; --j)
f[j] = max(f[j], f[j - v[i]] + w[i]);
cout << f[m] << '\n';
return 0;
}
有了闫氏DP分析法,从此再也不怕DP问题!
AcWing - 闫氏DP分析法的更多相关文章
- 【闫式dp分析法】
- Procrustes Analysis普氏分析法
选取N幅同类目标物体的二维图像,并用上一篇博文的方法标注轮廓点,这样就得到训练样本集: 由于图像中目标物体的形状和位置存在较大偏差,因此所得到的数据并不具有仿射不变性,需要对其进行归一化处理.这里采用 ...
- 从Elo Rating System谈到层次分析法
1. Elo Rating System Elo Rating System对于很多人来说比较陌生,根据wikipedia上的解释:Elo评分系统是一种用于计算对抗比赛(例如象棋对弈)中对手双方技能水 ...
- AX中四种库存ABC分析法原理研究
库存ABC分类,简单的说就是抓大放小,是为了让我们抓住重点,用最大精力来管理最重要的物料,而对于不太重要的物料则可以用较少的精力进行管理.它和我们平常说的八二法则有异曲同工之妙. 既然要应用库存ABC ...
- 黑盒测试用例设计方法&理论结合实际 -> 边界值分析法
一. 概念 边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法.通常边界值分析法是作为对等价类划分法的补充,这种情况下,其测试用例来自等价类的边界. 二. 边界值分析法的应用 根据大量的测 ...
- 帕累托分析法(Pareto Analysis)(柏拉图分析)
帕累托分析法(Pareto Analysis)(柏拉图分析) ABC分类法是由意大利经济学家帕雷托首创的.1879年,帕累托研究个人收入的分布状态图是地,发现少数人收入占全部人口收入的大部分,而多数人 ...
- SWOT分析法
SWOT(Strengths Weakness Opportunity Threats)分析法,又称为态势分析法或优劣势分析法,用来确定企业自身的竞争优势(strength).竞争劣势(weaknes ...
- 5W1H分析法
"5W1H分析法"也叫"六何分析法",它是一种分析方法也可以说是一种创造技法.是对选定的项目.工序和操作,都要从原因(Why).对象(What).地点(Wher ...
- 【编译原理】语法分析LL(1)分析法的FIRST和FOLLOW集
近来复习编译原理,语法分析中的自上而下LL(1)分析法,需要构造求出一个文法的FIRST和FOLLOW集,然后构造分析表,利用分析表+一个栈来做自上而下的语法分析(递归下降/预测分析),可是这个FIR ...
- 2017人生总结(MECE分析法)
试着用MECE分析法对人生的整个规划做一下总结.作为技术人员,其实除了编码架构能力之外,分析问题的能力的重要程度也会随着职业发展越来越重要.<美团点评技术博客>说这几天要在黄金时段头版头条 ...
随机推荐
- STL-queue(ACM)
重构函数(默认) queue<int> q; 基本操作 q.front(); // 队列最前面的元素q.back(); // 队列最后面的元素q.size(); // 返回队列长度q.em ...
- 【python基础】复杂数据类型-字典(遍历)
一个字典可能只包含几个键值对,也可能包含数百万个键值对,所以Python支持字典遍历.字典可用于以各种方式存储信息,因此有多种遍历字典的方式:可遍历字典的所有键值对.键或值. 1.遍历所有的键值对 其 ...
- Android-NDK开发——基本概念
在Android开发中,有时候出于安全,性能,代码共用的考虑,需要使用C/C++编写的库.虽然在现代化工具链的支持下,这个工作的难度已经大大降低,但是毕竟万事开头难,初学者往往还是会遇到很多不可预测的 ...
- Grafana 系列-GaC-2-Grafana Terraform Provider 基础
系列文章 Grafana 系列文章 Terraform 系列文章 概述 前文最后总结了我的工具选型: Grafana Terraform provider Jsonnet 我们今天先简单介绍 Graf ...
- maven项目中Tomcat启动失败:Failed to execute goal org.apache.tomcat.maven:tomcat7-maven-plugin:2.1:run
maven项目中Tomcat启动失败:Failed to execute goal org.apache.tomcat.maven:tomcat7-maven-plugin:2.1:run (defa ...
- CAN转PROFINET协议网关 JM-PN-CAN
1 产品功能 捷米特JM-PN-CAN 是自主研发的一款 PROFINET 从站功能的通讯网关.主要功能是将各种 CAN 设备接入到 PROFINET 网络中. 捷米特JM-PN-CAN连接到 ...
- 基于python+django的宠物商店-宠物管理系统设计与实现
该系统是基于python+django开发的宠物商店-宠物管理系统.是给师妹开发的课程作业.现将源码开放给大家.大家学习过程中,如遇问题可以在github咨询作者. 演示地址 前台地址: http:/ ...
- Elementary OS old version download 旧版本下载
Elementary OS 号称是最漂亮的Linux发行版,没有之一.确实,他的整体风格看起来就是特别舒服,说不出哪里特别好,但也挑不出什么毛病.相比之下,其他Linux的界面总感觉不太和谐.比如特别 ...
- sql-lab通关
page1-less1-22 联合查询 第一关 发现是有回显的,且传入的参数是通过'1'包裹的,所以我们的payload,如下 测试列数 ?id=1' order by 3 --+ //超过第一条语句 ...
- 好用工具:Wappalyzer
说明 这个插件可以检测到网站使用的技术栈,是一个好玩的技术嗅探插件 安装 使用