暑假集训每日一题0719 (01背包)

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背包,最后把对应体积的结果相加即可。
 
View Code
#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;
}
原文地址:https://www.cnblogs.com/algorithms/p/2599083.html