多人背包

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. Equals相關的一些要點

    什麽時候需要覆蓋Equals? 自定義的值類型需要覆蓋,因爲框架默認的實現是基於反射的,效率不高. 自定義的引用類型要根據業務需要來決定是否提供覆蓋.    什麽時候需要覆蓋operator==()? ...

  2. Why use Cache-Control header in request?

    本地缓存也是缓存代理的一部分. 请求时使用Cache-Control 表示缓存的使用策略. 请求头里的no-cache表示浏览器不想读缓存,并不是说没有缓存.一般在浏览器按ctrl+F5强制刷新时,请 ...

  3. openstack--rabbitmq

    一.MQ 全称为 Message Queue, 消息队列( MQ ) 是一种应用程序对应用程序的通信方法.应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们. 消息传 ...

  4. 模拟登录新浪微博(Python)

    PC 登录新浪微博时, 在客户端用js预先对用户名.密码都进行了加密, 而且在POST之前会GET 一组参数,这也将作为POST_DATA 的一部分. 这样, 就不能用通常的那种简单方法来模拟POST ...

  5. 【转载】Java 集合详解

    转载:https://www.cnblogs.com/ysocean/p/6555373.html 一.集合的由来 通常,我们的程序需要根据程序运行时才知道创建多少个对象.但若非程序运行,程序开发阶段 ...

  6. PAT_A1147#Heaps

    Source: PAT A1147 Heaps (30 分) Description: In computer science, a heap is a specialized tree-based ...

  7. 继续聊WPF——设置网格控件列标题的样式

    我很奇怪的是,微软那厮是怎么搞的,Blend里面居然不能编辑GridView的样式,十万般无奈之下,只好手写XAML来处理了. 要想知道一个控件的样式是如何设置,看控件类的定义很重要,我们来看看Gri ...

  8. Git 基础教程 之 创建与合并分支

  9. win7下qt+opencv的环境配置

    博客http://blog.csdn.net/qiurisuixiang/article/details/8665278已经完整地介绍了整个环境配置.需要一步不差按原执行.需要说明的是,几个path的 ...

  10. 安全性测试AppScan工具使用实战

    1.打开appScan 2.点击创建新的扫描[这里我选的是常规扫描] 3.进入配置向导页面,点击下一步 4..进入扫描配置向导页面,url输入http://www.baidu.com(可以打开appS ...