版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lizhaowei213/article/details/51165853
1086: 超市购物
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 361 Solved: 151
[ Submit][ Status][ Web Board]
Description
上次去超市扫荡回来的东西用完了,Staginner又得跑超市一趟,出发前他列了一张购物清单,打算去买K种不同的商品,每种买一件。到了超市,Staginner发现每种商品有N个品牌,每个品牌此商品的价格为Vi,对Staginner的作用值为Wi,他会从这N个品牌里面挑一个品牌买。这时,Staginner突然想起出门时只带了M元钱,又懒得去取钱了,所以不一定能买完K种商品,只好尽可能地让买的东西对自己的总作用值ans最大。
Input
多组样例。
第一行两个整数K,M代表Staginner想买的不同种类商品的数目和他带的钱 (0 < K <= 30, 0 < M <= 2000)
以下输入分为K个部分,代表K种商品。
每个部分第一行为一个数字N,代表第k种商品的N个品牌,N不大于10。之后跟着N行,每行两个数字,代表物品的价格Vi和作用值Wi。其中 0 < Vi < M。
Output
输出Case #: 最大总作用值,每两个样例之间有一个空行。
Sample Input
3 100
3
50 600
20 700
30 800
2
30 500
40 600
1
60 200
2 500
2
200 1000
260 1200
1
280 300
Sample Output
Case 1: 1400
Case 2: 1300
HINT
分组背包问题
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int MAXN=35;
const int MAXM=2005;
int weight[MAXN][MAXN],value[MAXN][MAXN];
int dp[MAXM];
int main()
{
int k,m;
int c=1;
while(scanf("%d%d",&k,&m)>0)
{
memset(dp,0,sizeof(dp));
memset(weight,0,sizeof(weight));
memset(value,0,sizeof(value));
for(int i=1;i<=k;i++)
{
int n;
scanf("%d",&n);
weight[i][0]=n;
for(int j=1;j<=n;j++)
scanf("%d%d",&weight[i][j],&value[i][j]);
}
for(int i=1;i<=k;i++)
for(int j=m;j>=0;j--)
for(int p=1;p<=weight[i][0];p++)
if(weight[i][p]<=j)
dp[j]=max(dp[j],dp[j-weight[i][p]]+value[i][p]);
printf("Case %d: %d\n\n",c++,dp[m]);
}
return 0;
}