多人背包

DD 和好朋友们要去爬山啦!他们一共有 K 个人,每个人都会背一个包。这些包的容量是相同的,都是 V。可以装进背包里的一共有 N 种物品,每种物品都有给定的体积和价值。
在 DD 看来,合理的背包安排方案是这样的:
1. 每个人背包里装的物品的总体积恰等于包的容量。 
2. 每个包里的每种物品最多只有一件,但两个不同的包中可以存在相同的物品。 
3. 任意两个人,他们包里的物品清单不能完全相同。 
在满足以上要求的前提下,所有包里的所有物品的总价值最大是多少呢?

输入格式:

第一行有三个整数:K、V、N。
第二行开始的 N 行,每行有两个整数,分别代表这件物品的体积和价值。

输出格式:

只需输出一个整数,即在满足以上要求的前提下所有物品的总价值的最大值。

样例输入:

2 10 5
3 12
7 20
2 4
5 6
1 1

样例输出:

57

数据范围:

总人数 K<=50。
每个背包的容量 V<=5000。
物品种类数 N<=200。
其它正整数都不超过 5000。
输入数据保证存在满足要求的方案。

 
解题思路:
读完题目,大概学过的人都知道是背包,只是具体怎么做的问题
***如果没学过背包问题的人,一定要去学学,这个是dp的基础,建议学习《背包九讲》
如果是单纯的01背包,f[j]=f[j-a[i]]+v[i]
那么这样只能计算最优解,如果要计算k优解呢?
我们可以增加一维,来记录当前状态下,即装了j的空间的时候的k优解
那么我们的转移就有点问题了,如何将f[j-a[i]]这样一个vector转化到f[j]这个vector
这里我们要提到归并排序,把两个有序数组合并的方法
***如果不会把两个有序数组合并的,也建议先去学习一下,这也是联赛的基础
那么这里便是把f[j]和f[j-a[i]]两个有序vector合并了
%:pragma GCC optimize()
#include<bits/stdc++.h>
using namespace std;
const int N=,K=;
int k,v,n,ans;
int a[N],va[N],res[K],f[N][K];
int main(){
scanf("%d%d%d",&k,&v,&n);
for (int i=;i<=n;++i)
scanf("%d%d",&a[i],&va[i]);
for (int i=;i<=v;++i)
for (int j=;j<=k+;++j)
f[i][j]=-;
f[][]=;
for (int i=;i<=n;++i)
for (int j=v;j>=a[i];--j)
if (f[j-a[i]][]!=-){
int l1=,l2=,tot=;
while (l1<=k&&l2<=k){
if (f[j][l1]==-||f[j-a[i]][l2]==-) break;
if (f[j][l1]>=f[j-a[i]][l2]+va[i])
res[++tot]=f[j][l1],l1++;
else res[++tot]=f[j-a[i]][l2]+va[i],l2++;
}
if (f[j][l1]==-)
while (l2<=k&&f[j-a[i]][l2]!=-) res[++tot]=f[j-a[i]][l2]+va[i],l2++;
else if (f[j-a[i]][l2]==-)
while (l1<=k&&f[j][l1]!=-) res[++tot]=f[j][l1],l1++;
for (int l=;l<=min(tot,k);++l) f[j][l]=res[l];
}
for (int i=;i<=k;++i)
ans+=f[v][i];
printf("%d",ans);
}

总结:这道也算是背包问题的一点拓展,当然还有更多的问题等着读者去解决

[XJOI]noip43 T2多人背包的更多相关文章

  1. P1858 多人背包

    P1858 多人背包 题目描述 求01背包前k优解的价值和 要求装满 调试日志: 初始化没有赋给 dp[0] Solution 首先补充个知识点啊, 要求装满的背包需要初始赋 \(-inf\), 边界 ...

  2. 洛谷 P1858 多人背包 解题报告

    P1858 多人背包 题目描述 求01背包前k优解的价值和 输入输出格式 输入格式: 第一行三个数\(K\).\(V\).\(N\) 接下来每行两个数,表示体积和价值 输出格式: 前k优解的价值和 说 ...

  3. [洛谷P1858] 多人背包

    洛谷题目链接:多人背包 题目描述 求01背包前k优解的价值和 输入输出格式 输入格式: 第一行三个数K.V.N 接下来每行两个数,表示体积和价值 输出格式: 前k优解的价值和 输入输出样例 输入样例# ...

  4. 背包【p1858】 多人背包(次优解 or 第k优解)

    题目描述--->p1858 多人背包 分析: 很明显,这题是背包问题的一种变形. 求解 次优解or第k优解. 表示刚开始有点懵,看题解也看不太懂. 又中途去补看了一下背包九讲 然后感觉有些理解, ...

  5. 洛谷 P1858 多人背包 DP

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 题面 题目链接 洛谷 P1858 多人背包 题目描述 求01背包前k优解的价值 ...

  6. 洛谷 P1858 多人背包

    求01背包前k优解的价值和 输入输出格式 Input/output 输入格式:第一行三个数K.V.N(k<=50,v<=5000,n<=200)接下来每行两个数,表示体积和价值输出格 ...

  7. 【动态规划】【归并】Vijos P1412 多人背包

    题目链接: https://vijos.org/p/1412 题目大意: 求01背包的前K优解,要求必须装满(1<=K<=50 0<=V<=5000 1<=N<=2 ...

  8. luogu P1858 多人背包

    嘟嘟嘟 既然让求前\(k\)优解,那么就多加一维,\(dp[j][k]\)表示体积为\(j\)的第\(k\)优解是啥(\(i\)一维已经优化掉了). 考虑原来的转移方程:dp[j] = max(dp[ ...

  9. 【洛谷P1858】多人背包

    题目大意:求解 0-1 背包前 K 优解的和. 题解:首先,可知对于状态 \(dp[j]\) 来说,能够转移到该状态的只有 \(dp[j],dp[j-w[i]]\).对于 K 优解来说,只需对状态额外 ...

随机推荐

  1. sql server 存储过程(事务,带参数声明,数据库瘦身)

    CREATE PROCEDURE procedureName (@var1 as varchar(50),@var2 as varchar(50)) --建立未发临时表 AS begin tran - ...

  2. JSP_内置对象_session

    session表示客户端与服务器的一次会话. Web中的session指的是用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间. 从上述定义中可以看到,s ...

  3. HTML DIV中文字自动换行 , 顶部对齐

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta ht ...

  4. vue遇到的大坑,h5在ios10版本下不能打开页面

    无论是谁,在做事情的过程中总是会遇到学坑,才能成为最后的大神 这个坑不说了,找了半天.希望能帮助到你们 进入build文件夹: 找到webpack.prod.conf.js文件: 在UglifyPlu ...

  5. javeee 字节Buffered

    package Zy; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io. ...

  6. EL截取url中参数

    function getUrlString(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*) ...

  7. JavaScript for循环元素取下标问题

    <ul> <li>fg</li> <li>gd</li> <li>gds</li> <li>ghe< ...

  8. 国庆day2

    a[问题描述]你是能看到第一题的 friends呢.—— hja世界上没有什么比卖的这 贵弹丸三还令人绝望事了,所以便么一道题.定义

  9. [luogu2414 NOI2011]阿狸的打字机 (AC自动机)

    传送门 Solution 我们知道AC自动机上如果有一点A的fail[A]->B那么B为A的一个后缀 那么我们的问题\((x,y)\)就变为在y中有多少个点直接或间接连向x的终止节点 如果写暴力 ...

  10. Golang - 复合类型

    目录 Golang - 复合类型 1. 指针 2. new()和make() 3. 数组 4. slice 5. Map 6. 结构体 7. 结构体参数 Golang - 复合类型 1. 指针 go语 ...