Description
听说附近的超市有N种商品打折促销,每种商品的单价为 Ci,实际价值为Wi。你和你的朋友们决定去超市购物,当然你们要买的东西已经包括在这N种商品中。一行A个人就往超市走了,到了超市被促销员告知每种商 品每人限购一件,让大家都有些许遗憾。你们每个人身上都带了一定数额的钱M,每个人都想用自己的钱买到总价值最大的一些商品。现在,你想知道所有人买的商 品总的实际价值是多少?
Input
多组测试数据直到文件末尾。
第一行输入A和N(0 < A <= 50, 0 < N <= 1000)代表人数和商品种数。
第二行输入A个数,表示每个人身上带的钱Mi(0 < Mi <= 2000)。
以下N行,每行两个数字分别代表某种商品的单价Ci和实际价值Wi。
Output
一行Case #: ans
每两个样例之间有空行。
Sample Input
5 4
6 5 3 7 8
1 4
2 6
2 7
3 12
5 6
6 7 8 9 10
1 3
2 6
2 7
1 5
3 12
4 20
Sample Output
Case 1: 108
Case 2: 181
先找出最大的背包体积,然后用这个V去做01背包,最后把对应体积的结果相加即可。

#include <stdio.h> #include <string.h> #define MAX(a,b) ((a)>(b)?(a):(b)) #define V 2010 int f[V]; int a[51]; int main() { int x,n,ans; int i,j,kase=0; int v,w,maxv; while(~scanf("%d%d",&x,&n)) { maxv=0; for(i=0;i<x;i++) scanf("%d",&a[i]),maxv=MAX(a[i],maxv); memset(f,0,sizeof(f[0])*(maxv+2)); for(i=0;i<n;i++) { scanf("%d%d",&v,&w); for(j=maxv;j>=v;j--) f[j]=MAX(f[j],f[j-v]+w); } ans=0; for(i=0;i<x;i++) ans+=f[a[i]]; if(kase) puts(""); printf("Case %d: %d\n",++kase,ans); } return 0; }