洛谷 1858 多人背包
https://www.luogu.org/problem/show?pid=1858
题目描述
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\le 50,V\le 5000,N\le 200K≤50,V≤5000,N≤200
dp[i][j] 表示体积为i时的第j优解
取能够更新的前k优解,排好序后 赋值给dp[i][j]
#include<cstdio> #include<cstring> #include<iostream> #define N 201 #define M 5001 #define K 51 using namespace std; int v[N],w[N]; int f[M][K],tmp[K]; void read(int &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } } int main() { int k,m,n; read(k); read(m); read(n); for(int i=1;i<=n;i++) read(v[i]),read(w[i]); int pos,a,b; memset(f,-63,sizeof(f)); f[0][1]=0; for(int i=1;i<=n;i++) for(int j=m;j>=v[i];j--) { pos=a=b=1; while(pos<=k) { if(f[j][a]>=f[j-v[i]][b]+w[i]) tmp[pos++]=f[j][a++]; else tmp[pos++]=w[i]+f[j-v[i]][b++]; } for(pos=1;pos<=k;pos++) { f[j][pos]=tmp[pos]; printf("%d %d %d %d\n",i,j,pos,f[j][pos]); } } int ans=0; for(int i=1;i<=k;i++) ans+=f[m][i]; printf("%d",ans); return 0; }