[ACM学习] 背包问题深化

01背包的优化

因为我们更新数据时,都是从左到右进行更新的,所以我们可以把二维的dp变成一维的dp,并从后往前进行更新(这样可以保证进行更新的数据都是由旧数据更新新数据,而不是由新数据更新旧数据)

多重背包

朴素的想法就是把s个物品重复一遍,这样就是O(n*m*s),容易超时,所以想想,怎么优化。

有点像倍增的思想,用1 2 4...等等数字,是因为二进制数可以表示任何数字,如果最后有剩余,就把那个剩余单独一组。

#include<iostream>
#include<algorithm>
using namespace std;
#define ll long longll dp[20005];int main()
{int n,m;cin >> n >> m;for(int i = 1 ; i <= n ; i++){ll w,v,s;cin >> w >> v >> s;//s = 14for(int k=1 ; k <= s ; s-=k,k+=k ){//k = 1 2 4 ...for(int j = m ; j >= k*w ; j--){dp[j]=max(dp[j],dp[j-k*w]+k*v);}}//s 还有一部分剩余for(int j = m ; j >= s*w ; j--){dp[j]=max(dp[j],dp[j-s*w]+s*v);}}cout << dp[m];return 0;
}

s-=k,k+=k 保证了每次k是1 2 4...然后s是剩余的、还没有进行相加的数字,如果不满足下一个2的倍数,就自成一组。

单调队列优化多重背包

把时间复杂度降到O(n*m)

就是在 (不放物品、只放1个、放2个、......、放s个)这里面挑个最大值。

第一维可滚掉的意思是:可以把这个数组从后到前进行遍历,来个n次(第次的n都是一个新的物品)。

解释,毕竟这个物品,体积是v,在分完组之后,能对它进行影响的只有 j-v 那个点的值了。

代码。。。找了好多地方的,终于找到一个靠谱的且我能理解的。

以下是通过蓝桥题目的代码。

#include <iostream>
#include <queue>
#include <utility>
#include <algorithm>
using namespace std;
#define ll long longconst int N = 2e4+5;
pair<int,int> q[N];
ll dp[N];
int head,tail;int main()
{int n,V;cin >> n >> V;for(int i = 1 ; i <= n ; i++){int v,w,s;cin >> v >> w >> s;int num = min(V/v,s);for(int mo = 0 ; mo < v ; mo++){head=0,tail=0;for(int k = 0 ; k <= (V-mo)/v ; k++){int y=dp[k*v+mo]-k*w;int x=k;while(head<tail && q[head].first<k-num) head++;while(head<tail && q[tail-1].second<=y) tail--;q[tail++]={x,y};dp[k*v+mo]=q[head].second + k*w;}}}cout << dp[V];return 0;
}

费用背包模型

只是多一个维度,代码如下:

int main()
{// 请在此输入您的代码int n,V,M;cin >> n >> V >> M;for(int i = 1 ; i <= n ; i++){int v,m,w;cin >> v >> m >> w;for(int j = V ; j >= v ; j--){for(int k = M ; k >= m ; k--){dp[j][k]=max(dp[j][k],dp[j-v][k-m]+w);}}}cout << dp[V][M];return 0;
}

分组背包

每组只能挑一个,可以不挑。

对dp[i][j] 会有 s 次的更新,因为要和同组内进行竞争,所以找dp[i][j]的max会和当时dp[i][j]的值进行对比,为了不漏 dp[i-1][j] ,所以要在组内循环前把 dp[i][j]=dp[i-1][j] 方便之后对比。

int main()
{// 请在此输入您的代码int n,V;cin >> n >> V;for(int i = 1 ; i <= n ; i++){for(int j = 1 ; j <= V ; j++){dp[i][j]=dp[i-1][j];}int s;cin >> s;while(s--){int w,v;cin >> w >> v;for(int j = w ; j <= V ; j++){dp[i][j]=max(dp[i][j],dp[i-1][j-w]+v);}}}cout << dp[n][V];return 0;
}

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

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

相关文章

LeetCode-135】分发糖果(贪心)

LeetCode135.分发糖果 题目描述 老师想给孩子们分发糖果&#xff0c;有 N 个孩子站成了一条直线&#xff0c;老师会根据每个孩子的表现&#xff0c;预先给他们评分。 你需要按照以下要求&#xff0c;帮助老师给这些孩子分发糖果&#xff1a; 每个孩子至少分配到 1 个糖果。…

探索设计模式的魅力:一次设计,多次利用,深入理解原型模式的设计艺术

原型模式是一种设计模式&#xff0c;属于创建型模式的一种&#xff0c;它用于创建重复的对象&#xff0c;同时又能保持性能。在原型模式中&#xff0c;通过复制现有对象的原型来创建新对象&#xff0c;而不是通过实例化类来创建对象。这样做可以避免耗费过多的资源开销&#xf…

docker compose安装milvus

下载对应版本的milvus-standalone-docker-compose.yml wget https://github.com/milvus-io/milvus/releases/download/v2.3.5/milvus-standalone-docker-compose.yml重新命令为docker-compose.yml mv milvus-standalone-docker-compose.yml docker-compose.yml启动milvus doc…

《WebKit 技术内幕》学习之九(4): JavaScript引擎

4 实践——高效的JavaScript代码 4.1 编程方式 关于如何使用JavaScript语言来编写高效的代码&#xff0c;有很多铺天盖地的经验分享&#xff0c;以及很多特别好的建议&#xff0c;读者可以搜索相关的词条&#xff0c;就能获得一些你可能需要的结果。同时&#xff0c;本节希望…

074:vue+mapbox 加载here地图(影像瓦片图 v2版)

第074个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中加载here地图的影像瓦片图 v2软件版本。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共77行)相关API参考:专栏目标示例效果

C++ 实现游戏(例如MC)键位显示

效果&#xff1a; 是不是有那味儿了&#xff1f; 显示AWSD&#xff0c;空格&#xff0c;Shift和左右键的按键情况以及左右键的CPS。 彩虹色轮廓&#xff0c;黑白填充。具有任务栏图标&#xff0c;可以随时关闭字体是Minecraft AE Pixel&#xff0c;如果你没有装&#xff08;大…

IO流(一):字节流

file是java.io.包下的类&#xff0c;file类的对象&#xff0c;用于代表当前操作系统的文件(可以是文件或者文件夹) file类只能对文件本身进行操作&#xff0c;不能读写文件里面存储的数据 IO流用于读写数据 file代表文本 File 构造方法 File(String pathname)//通过将给定…

网络安全的概述

网络空间的概念 2003年美国提出网络空间的概念&#xff1a;一个由信息基础设施组成的互相依赖的网络。 我国官方文件定义&#xff1a;网络空间为继海&#xff0c;陆&#xff0c;空&#xff0c;天以外的第五大人类活动领域 网络安全发展历史 通信保密阶段 --- 计算机安全阶段…

柔性数组和C语言内存划分

柔性数组和C语言内存划分 1. 柔性数组1.1 柔性数组的特点&#xff1a;1.2 柔性数组的使用1.3 柔性数组的优势 2. 总结C/C中程序内存区域划分 1. 柔性数组 也许你从来没有听说过柔性数组&#xff08;flexible array)这个概念&#xff0c;但是它确实是存在的。 C99 中&#xff…

React16源码: React中的completeUnitOfWork的源码实现

completeUnitOfWork 1 &#xff09;概述 各种不同类型组件的一个更新过程对应的是在执行 performUnitOfWork 里面的 beginWork 阶段它是去向下遍历一棵 fiber 树的一侧的子节点&#xff0c;然后遍历到叶子节点为止&#xff0c;以及 return 自己 child 的这种方式在 performUni…

【小白学机器学习3】关于最简单的线性回归,和用最小二次法评估线性回归效果, 最速下降法求函数的最小值

目录 1 什么是回归分析 1.1 什么是线性回归 1.2非线性回归 2 数据和判断方法 2.1 原始数据 2.2 判断方法&#xff1a;最小二乘法 3 关于线性回归的实测 3.1 用直线模拟 3.2 怎么判断哪个线性模拟拟合更好呢&#xff1f; 3.2.1 判断标准 3.2.2 最小二乘法 3.2.3 高维…

Consul使用详解

简介 Consul是一个由HashiCorp公司开发的开源软件&#xff0c;其发展历程可以概括为以下几个阶段&#xff1a; 初期阶段&#xff08;2014-2015年&#xff09;&#xff1a;Consul最初发布于2014年5月&#xff0c;这个版本是基于Go语言开发的&#xff0c;并提供了诸如服务发现、…