当前位置:网站首页>洛谷P1858 【多人背包】 (背包求前k优解)
洛谷P1858 【多人背包】 (背包求前k优解)
2022-04-23 04:02:00 【glorious_dream】
题目描述:
重点:求 01 背包前 k 优解的价值和,并且背包要装满。
算法分析:
首先,01 背包大家应该很熟悉了,这里就不讲转移式了。
先讲第一部分:如何保证背包装满?
正常的 01 背包是从数组初始值为 0 开始,也就是说每一种体积都会转移,有可能会更新答案。
但如果要装满,显然,装不满的体积(也就是没有 n 个物品的体积和能为这个体积)显然不能要。似乎感觉很难,但没关系,我们把 f 数组先赋值为最小值。
这样有什么好处?会发现,因为是一层一层往下刷,那么第一层显然只有体积正好为第一个物品的那个体积,会更新最大值(因为别的都是负无穷,不会更新)。
然后开始刷第二层,显然,只有在第一层刷过的那个体积,才会接着往后转移(因为转移别的都是从负无穷转移过来的,没有意义,不可能是最大值)。
然后注意 ff 数组要有一个初始值是 0 (后面讲)。
来看第二部分:求前 k 优解的价值和。
设 f[i][j] 表示体积为 i,第 j 优解的值。这时,上面说的 f 数组初始值就可以赋值了。把 f[0][1] 赋值为 0,因为体积为 0 的最优解显然是 0。
我们需要考虑前 k 优解。从最优解开始往后找。
01 背包是 f[j] 和 f[j−w[i]]+v[i] 的转移,那么这道题可以借鉴这种思路。
设 x,y 分别为两边的最优解。如果 f[j][x]>f[j−w[i]][y],我们用一个数组 rnk 来存前 k 优解,这时 rnk[++cnt]=f[j][x],并且把 x+1。反之同理。
这段话表示什么?就是记录这两种背包的容量,哪一种是大的。
最后在外面把 f 数组在容积为 j 的条件下的前 k 优解赋值为 rnk 数组的前 k 个就可以了。
总代码:
#include<bits/stdc++.h>
#define re register
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch == '-') f=-1 ; ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48) ; ch=getchar();}
return x*f;
}
inline void print(int x){
if(x/10) print(x/10);
putchar(x%10+'0');
}
const int M = 5010;
int k,value,n,ans;
int w[M],v[M],f[M][60],rnk[M];
signed main(){
k=read(),value=read(),n=read();
for(re int i(1) ; i<=n ; ++i) scanf("%d%d",&w[i],&v[i]);
memset(f,-0x7f7f7f7f,sizeof(f));
f[0][1] = 0;
for(re int i(1) ; i<=n ; ++i){
for(re int j(value) ; j>=w[i] ; --j){
int rn1=1,rn2=1,cnt=0;
while(cnt<=k){
if(f[j][rn1] > f[j-w[i]][rn2]+v[i]){
rnk[++cnt] = f[j][rn1];
rn1++;
}
else{
rnk[++cnt] = f[j-w[i]][rn2]+v[i];
rn2++;
}
}
for(re int h(1) ; h<=k ; ++h) f[j][h] = rnk[h];
}
}
for(re int i(1) ; i<=k ; ++i) ans += f[value][i];
printf("%d",ans);
return 0;
}
版权声明
本文为[glorious_dream]所创,转载请带上原文链接,感谢
https://blog.csdn.net/glorious_dream/article/details/124344817
边栏推荐
- STM32F4单片机ADC采样及ARM-DSP库的FFT
- Process seven state transition diagram
- Zotero6. Version 0 quicklook cannot be used / Chinese garbled code will not be displayed
- Qtspim manual - Chinese Translation
- Operating skills of spot gold_ Wave estimation curve
- TreeSet课后练习
- 网络原理 | TCP/IP中的连接管理机制 重要协议与核心机制
- ROS series (IV): ROS communication mechanism series (5): Service Communication Practice
- What if you encounter symbols you don't know in mathematical formulas
- 【BIM+GIS】ArcGIS Pro2. 8 how to open Revit model, Bim and GIS integration?
猜你喜欢
作为一名码农,女友比自己更能码是一种什么体验?
[latex] formula group
Process seven state transition diagram
Writing latex with vscode - the latest tutorial 2022 / 4 / 17
Xshell、Xftp连接新创建的Unbutu系统虚拟机全流程
Installation and configuration of clion under win10
Cortex-M3寄存器组、汇编语言与C语言的接口介绍
Shopping mall for transportation tools based on PHP
知乎有问题,谁来解答?
创下国产手机在海外市场销量最高纪录的小米,重新关注国内市场
随机推荐
According to the category information and coordinate information of the XML file, the category area corresponding to the image is pulled out and stored in the folder.
【BIM入门实战】Revit建筑墙体:构造、包络、叠层图文详解
STM32F4单片机ADC采样及ARM-DSP库的FFT
【测绘程序设计】坐标方位角推算神器(C#版)
Numpy's broadcasting mechanism (with examples)
[AI vision · quick review of robot papers today, issue 28] wed, 1 Dec 2021
VS Studio 修改C語言scanf等報錯
Paddlepaddle model to onnx
【李宏毅2022 机器学习春】hw6_GAN(不懂..)
[latex] formula group
单极性非归零NRZ码、双极性非归零NRZ码、2ASK、2FSK、2PSK、2DPSK及MATLAB仿真
The great gods in acmer like mathematics very much
VSCode配置之Matlab极简配置
[AI vision · quick review of today's sound acoustic papers issue 1] Thu, 14 APR 2022
Nel ASA:挪威Herøya设施正式启用
阿里云IoT流转到postgresql数据库方案
Key point detection of human hand based on mediapipe
Counting and sorting (C language implementation) -- learning notes
【测绘程序设计】坐标反算神器V1.0(附C/C#/VB源程序)
Solve the technical problems in seq2seq + attention machine translation