您的位置:首页 > 其它

Vijos P1412 多人背包

2016-09-13 21:11 225 查看
P1412多人背包Accepted标签:[显示标签]

描述

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

格式

输入格式

第一行有三个整数:K、V、N( 1 <= K <= 50, 0 <= V <= 5000,1 <= N <= 200 )。第二行开始的 N 行,每行有两个整数,分别代表这件物品的体积和价值。

输出格式

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

样例1

样例输入1[复制]

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

样例输出1[复制]

57

限制

各个测试点1s

来源

感谢dd_engi

多人4000背包
也就是求背包的第k优解
如果是求最优解dp[i][j],那么只需要求max(dp[i - 1][j],dp[i - 1][j - w[i]] + p[i])
那么求k优解dp[i][j][1~k],那么只需要求dp[i - 1][j]的前k优解(有序)和dp[i - 1][j - w[i]] + p[i] 的前k优解(有序)
那么两个数组归并到dp[i][j][1~k]中,取前k优解即可。
那么dp[i]只与dp[i - 1]有关,所以可以少开一维空间
膜拜大牛博客
代码:
/**多人背包link=**/#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#define maxn (4000 + 20)#define inf 0x3f3f3f3f#define pi acos(-1.0)using namespace std;typedef long long int LLI;int list1[maxn];int list2[maxn];int dp[5500][55];int main() {//    freopen("in.txt","r",stdin);//    freopen("out.txt","w",stdout);int n,m,k;scanf("%d%d%d",&k,&m,&n);for(int i = 0; i <= m; i ++)for(int j = 0; j <= k; j ++)dp[i][j] = -99999999;dp[0][1] = 0;for(int i = 1; i <= n; i ++) {int x,y;scanf("%d%d",&x,&y);for(int j = m; j >= x; j --) {int p = 1,q = 1,o = 1;for(int l = 1; l <= k; l ++) {list1[l] = dp[j][l];list2[l] = dp[j - x][l] + y;}while(o <= k) {if(list1[p] > list2[q] && p <= k)   dp[j][o ++] = list1[p ++];else if(list1[p] <= list2[q] && q <= k) dp[j][o ++] = list2[q ++];}}}int ans = 0;for(int i = 1; i <= k; i ++) {ans += dp[m][i];}printf("%d\n",ans);return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息