【典】dp背包问题(树求方案)

 回顾在acw上做过的题


 有依赖的背包问题

 

 这一题是与树相关的dp问题,根据父节点与子节点的相连关系,我们用dfs来处理根节点与子树的迭代更新,把每一颗最小单位子树看成一个物品,然后就有点像多重背包(因为有体积限制),又有点像01背包问题(每颗子树要么选要么不选)

f[ i ][ j ] 表示以i为根节点(包含i)的子树,总体积不超过j的最大价值。

然后画一颗dfs深搜树,在回溯的时候进行迭代更新

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>using namespace std;
const int N = 110;
int v[N],w[N];
vector<int> fa[N];
int f[N][N];
int n,m;void dfs(int x)
{for(int i = v[x]; i <= m; i ++) f[x][i] = w[x];//初始化每个节点在合法体积下的价值for(int i = 0; i < fa[x].size(); i ++){int t = fa[x][i];dfs(t); // dfs找到分支末端for(int j = m; j >= v[x]; j --) //要保证给根节点x赋值,所以体积至少为v[x]for(int k = 0; k <= j - v[x]; k ++) //因为要保证给根节点x赋值,所以给子树分配的体积要留剩下v[x]f[x][j] = max(f[x][j], f[x][j-k]+f[t][k]);}
}int main()
{cin>>n>>m;int root;for(int i = 1; i <= n; i ++){int p;cin>>v[i]>>w[i]>>p;if(p == -1) root = i;elsefa[p].push_back(i);}dfs(root);cout<<f[root][m];
}

背包问题求方案

 这道题抽象成多重背包问题。体积就是总共能分配出去多少台机器,k就是枚举给每一家子公司分配出去多少机器,对应的w[ i ][ k ]就是所获得的价值。

接下来就是求方案,这个问题就要思考我们的答案是怎么来的,是通过集合的迭代更新,一步步往后迭代得到f[ n ][ m ]的。那么我们只需要找到这个状态的前一个状态的关系,将他们链接起来,就可以找到具体转移过程中涉及的变量。

#include<iostream>
#include<cstring>
#include<algorithm>using namespace std;
const int N = 11, M = 16;
int f[N][M];
int w[N][M];
int n,m;
int path[N];
int main()
{cin>>n>>m;for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j ++)cin>>w[i][j];//用多重背包的思路来解决for(int i = 1; i <= n; i ++)for(int j = m; j >= 0; j--)for(int k = 0; k <= j; k ++)f[i][j] = max(f[i][j], f[i-1][j-k] + w[i][k]);cout<<f[n][m]<<endl;int j = m;for(int i = n; i >= 1; i--)for(int a = 0; a <= m; a ++){if(f[i-1][j-a] + w[i][a] == f[i][j]) //倒着求,寻找方案{path[i] = a;j -= a;break;}}for(int i = 1; i <= n; i ++) cout<<i<<' '<<path[i]<<endl;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/537001.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电脑音频显示红叉怎么办?这里提供四种方法

前言 如果你在系统托盘中看到音量图标上的红色X,则表示你无法使用音频设备。即使音频设备未被禁用,当你运行音频设备疑难解答时,仍然会看到此错误。 你的电脑将显示已安装高清音频设备,但当你将鼠标悬停在图标上时,它将显示未安装音频输出设备。这是一个非常奇怪的问题,…

掌握抽象基础之20个必备原则,看完你还不会,你打我

抽象基础之20个必备原则 1. 面向对象编程&#xff08;OOP&#xff09;中抽象原则背后的基本思想是什么&#xff1f;2.抽象和封装的区别&#xff1f;3.提供一个现实生活中说明抽象的例子4.在编程语言中如何实现抽象&#xff1f;5.定义抽象类6.提供一个抽象类的真实世界场景7.解释…

【洛谷 P8744】[蓝桥杯 2021 省 A] 左孩子右兄弟 题解(深度优先搜索+贪心算法+树形DP+邻接表)

[蓝桥杯 2021 省 A] 左孩子右兄弟 题目描述 对于一棵多叉树&#xff0c;我们可以通过“左孩子右兄弟”表示法&#xff0c;将其转化成一棵二叉树。 如果我们认为每个结点的子结点是无序的&#xff0c;那么得到的二叉树可能不唯一。换句话说&#xff0c;每个结点可以选任意子结…

深度学习系列62:Agent入门

1 anget介绍和openai标准接口 agent的核心是其代理协同工作的能力。每个代理都有其特定的能力和角色&#xff0c;你需要定义代理之间的互动行为&#xff0c;即当一个代理从另一个代理收到消息时该如何回复。 agent目前大多使用openai标准接口调用LLM服务&#xff0c;说明如下。…

从自媒体小白到优质KOL,你只差这些个人IP提效神器了!

在数字化浪潮的推动下&#xff0c;社交媒体已成为连接品牌与消费者的重要桥梁。然而&#xff0c;面对众多的社交平台、复杂的数据分析和日益增长的用户需求&#xff0c;社媒运营者常常感到力不从心。高效的社交媒体运营不仅可以提升品牌形象&#xff0c;还能促进产品销售&#…

Redisson分布式锁解决方案

官方地址 官网: https://redisson.org github: https://github.com/redisson/redisson 基于setnx实现的分布式锁存在的问题 redisson分布式锁原理 不可重入: 利用hash结构记录线程id和重入次数不可重试: 利用信号量和PubSub功能实现等待、唤醒, 获取锁失败的重试机制超时释放…

【Java设计模式】十九、中介者模式

文章目录 1、中介者模式2、案例3、总结 1、中介者模式 如图&#xff1a; 同事类之间关联较多时&#xff0c;整体出现网状结构&#xff0c;耦合度极高。一个对象一变动&#xff0c;好多对象都得改。若变为右边的星形结构&#xff0c;则一个类的变动&#xff0c;只影响自身与中介…

TypeScript -哲学 Mapped types

1、快速复制另一个类型 2、对之前的类型进行重写 3、 4、 注意&#xff1a;这里直接 报错&#xff1a;因为模版字符串只能包含 不能退出 k的来源&#xff0c;所以报错。 Remove a property from a type

php 对接Bigo海外广告平台收益接口Reporting API

今天对接的是Bigo广告reporting api接口&#xff0c;拉取广告收益回来自己做统计。记录分享给大家 首先是文档地址,进入到BIGO后台就能看到文档地址以及参数&#xff1a; 文档地址&#xff1a;https://www.bigossp.com/guide/sdk/reportingApi/doc?type1 接入这些第三方广告…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Text)

显示一段文本的组件。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 可以包含Span和ImageSpan子组件。 接口 Text(content?: string | Resource, value?: TextOptions) 从API versi…

掌控无显示器Linux开发板:VNC远程桌面接入指南

掌控无显示器Linux开发板&#xff1a;VNC远程桌面接入指南 Linux开发板是许多技术人员常用的工具&#xff0c;但有时它们并不配备显示器。这时&#xff0c;VNC&#xff08;Virtual Network Console&#xff09;软件就成为了一个非常有用的工具&#xff0c;它允许用户通过网络远…

小程序开发——获取设备信息 API(二)

ty.device.getDeviceNumWithDpCode 根据 dpCode 获取群组下具备此 dpCode 的设备数量。如果是一个分享的群组&#xff0c;请通过接口获取。 需引入DeviceKit&#xff0c;且在>2.4.0版本才可使用 请求参数 Object object 属性类型默认值必填说明groupIdstring是groupId 群…