【题解】P1858 多人背包
P1858 多人背包
题目描述
求01背包前k优解的价值和
DD 和好朋友们要去爬山啦!
他们一共有 K 个人,每个人都会背一个包。这些包 的容量是相同的,都是 V。可以装进背包里的一共有 N 种物品,每种物品都有 给定的体积和价值。
在 DD 看来,合理的背包安排方案是这样的: 每个人背包里装的物品的总体积恰等于包的容量。 每个包里的每种物品最多只有一件,但两个不同的包中可以存在相同的物品。
任意两个人,他们包里的物品清单不能完全相同。 在满足以上要求的前提下,所有包里的所有物品的总价值最大是多少呢?
输入格式
第一行三个数K、V、N
接下来每行两个数,表示体积和价值
输出格式
前k优解的价值和
输入输出样例
输入 #1
2 10 5
3 12
7 20
2 4
5 6
1 1
输出 #1
57
说明/提示
对于100%的数据,
K≤50,V≤5000,N≤200
题解
很多很多人,意思就是体积一样但是有很多很多不同的方案
状态:
$ f[i][j][k] $ 前i个人,体积为j,第k大的价值
决策:第i个物品选不选
归并转移
code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
using namespace std;
int k , V , n , ans;
int w[210] , v[210];
int now[55];
int f[5010][210] ;
int main()
{
cin >> k >> V >> n;
for (int i = 1 ; i <= n ; i++)
{
cin >> w[i] >> v[i];
}
for (int i = 0 ; i <= V ; i++)
{
for (int j = 1 ; j <= k ; j++) f[i][j] = -10000;
}
f[0][1] = 0;//体积为零时最优价值为0
//第2优、第3优、··第k优都要负无穷
for (int i = 1 ; i <= n ; i++)
{
for (int j = V ; j >= w[i] ; j--)
{
int cnt = 0 , c1 = 1 , c2 = 1;
while(cnt <= k)
{
if(f[j][c1] >= f[j - w[i]][c2] + v[i])
now[++cnt] = f[j][c1++];
else
now[++cnt] = f[j - w[i]][c2++] + v[i];
}
for (int c = 1 ; c <= k ; c++)
{
f[j][c] = now[c];
}
}
}
for (int i = 1 ; i <= k ; i++)
ans += f[V][i];
cout << ans << endl;
return 0;
}