首页 > 其他分享 >AcWing - 闫氏DP分析法

AcWing - 闫氏DP分析法

时间:2023-08-29 20:44:22浏览次数:48  
标签:状态 int 最大值 闫氏 集合 DP AcWing

核心思想:从集合角度来分析DP问题

在我们遇到的DP问题中,一般都是求在一个有限集内的最值,但是这些方案数量一般都是指数级别的,想要一个一个查找出来不太可能。所以DP方法是用来优化这种寻找最优方案的过程的。

DP问题一般来说分析时都要经过两个阶段:

  1. 状态表示(化零为整):指把一些具有相似点的方案,划分为一个子集,然后用一个状态来表示它。现在假设我们的状态表示为 \(f[i]\)。

    状态表示要从两个角度来分析:

    1. 集合:\(f[i]\) 表示的集合就是:所有满足xxx条件的集合。正是因为我们的 \(f[i]\) 可以表示一类东西而不是一个东西,这样就可以达到优化的作用。
    2. 属性:也就是我们状态存的这个值是这个集合的什么东西,也就是最大值/最小值/数量等等。
  2. 状态计算(化整为零):先看一下 \(f[i]\) 表示的所有状态是什么:

    比如说是这个集合:

    image

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

    image

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

举例:01背包问题

image

开始使用闫氏DP分析法!

  1. 状态表示:\(f[i][j]\)

    1. 集合:所有只考虑前 \(i\) 个物品,且总体积不超过 \(j\) 的选法的集合。
    2. 属性:Max(最大值)
  2. 状态计算:

    image

    想要取得最大值,只需要得出左边集合的最大值和右边集合的最大值就可以了。

    我们来看一下这两个子集分别是什么

    image

    完成!这样我们就成功地把这个问题推出来了。

这个问题还可以再继续优化,目前的状态表示是二维的,但是每次我们只会用到第 \(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问题!

标签:状态,int,最大值,闫氏,集合,DP,AcWing
From: https://www.cnblogs.com/popfront/p/17665786.html

相关文章

  • 对动态 DP 和全局平衡二叉树的一点补充解释
    说明:最近在帮高中竞赛教练写讲义,这是本人对讲义中动态DP内容的补充解释(因为主要是对知识点的理解,不太容易用通用的语言表述,也不适合作为讲义内容供读者阅读,所以用的是补充注释的形式)。写的比较抽象也比较初等,仅供意会。1.为什么用矩阵表示转移我们先从一般的角度,用映射的语言......
  • Cloudpods 私有云平台有哪些优势?
    作为一套完整的私有云管理软件,我们经常会被问到Cloudpods和其他的同类产品相比,有哪些优势?我总结了2个方面,供大家参考。功能方面产品化,开箱即用,易用性较高,基本上都可以傻瓜式的操作,当然有些牵扯到技术层面的问题,也免不了会有一些专业的概念或者操作。自动化安装部署裸机,支......
  • 【muduo】net篇---EventLoopThread和EventLoopThreadPool
    EventLoopThread是事件循环线程,包含一个Thread对象,一个EventLoop对象。在构造函数中,把EventLoopThread::threadFunc注册到Thread对象中(线程启动时会回调)。EventLoopThreadPool是事件循环线程池,管理所有客户端连接,每个线程都有唯一一个事件循环。可以调用setThreadNum设置线程的数......
  • 2023下半年杭州/广州/深圳NPDP产品经理国际认证开班啦
    产品经理国际资格认证NPDP是新产品开发方面的认证,集理论、方法与实践为一体的全方位的知识体系,为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会(PDMA)成立于1979年,是全球范围内产品开发与管理专业人士最杰出的倡导者,协助个人、企业或......
  • spring boot WebSocket @ServerEndpoint注解标识的class无法获取spring容器中的bean
    在@ServerEndpoint类中直接使用@Autowired注解注入Spring管理的bean可能不会成功,因为@ServerEndpoint并不受Spring容器的管理。通过创建一个静态的成员遍历属性和一个带有@Autowired注解的setter方法,你可以在类加载时将bean注入到静态属性中。但是,请注意这样做......
  • 数位DP详细解析
    1.定义与原理2.例题一:题目Acwing1081.度的数量思路我们做数位\(DP\)时,一般有如下两个技巧方便做题,理清思路:1.对于求一段数中满足条件的数的个数,可以用前缀和的方法完成,即$ans=dp(r)-dp(l-1)$;2.在想思路时,可以把问题转换成树的形式,对每个步骤分情况讨论,下面拿......
  • Acwing. 秋季每日一题
    Acwing.秋季每日一题活动链接A重复局面.国际象棋在对局时,同一局面连续或间断出现3次或3次以上,可由任意一方提出和棋。国际象棋每一个局面可以用大小为8×8的字符数组来表示,其中每一位对应棋盘上的一个格子。六种棋子王、后、车、象、马、兵分别用字母k、q、r、b、n、p......
  • CF1385 F. Removing Leaves 换根dp
    CF1385F.RemovingLeaves换根dp题目链接题意:给你一棵树,有一种操作,选择k个叶子,若叶子节点的父亲相同,则可删去这k个节点,问你最多能操作多少次。做法:这题的官方做法是贪心+bfs,不过用换根dp的方法也是可做的。首先我们常规选择节点1为根节点,跑一遍dfs,主要记录下面这些变量......
  • 网络直播源码UDP协议搭建:为平台注入一份力量
    网络直播源码中的UDP协议的定义:UDP协议又名用户数据报协议,是一种轻量级、无连接的协议。在网络直播源码平台中,UDP协议有着高速传输与实时性的能力,尤其是在网络直播源码实时性要求较高的场景,UDP协议的应用有着重要的意义。UDP协议在网络直播源码的好处:1. 高速实时传输:UDP协议是一种......
  • .NET CORE 终端路由中间件 app.UseEndpoints
    publicvoidConfigureServices(IServiceCollectionservices){services.AddControllers();}publicvoidConfigure(IApplicationBuilderapp,IWebHostEnvironmentenv){app.UseRouting();app.UseAuthorization();app.UseEndpoints......