您的位置:首页 > 其它

hdu 3033 I love sneakers!(分组背包)

2013-07-30 17:35 447 查看
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=3033

5 13 3

1  2  3

1 4  6

2 10 2

3  2  2

3 1  2

7

money k=0 k=1 k=2 k=3 

0     0    -1    -1    -1 

1            0    -1    -1    -1

2            0    3    -1    -1

3            0    3    -1    -1

4            0    6    -1    -1

5            0    6    -1    -1

6            0    9    -1    -1

7            0    9    -1    -1

8            0    9    -1    -1

9            0    9    -1    -1

10         0    9    -1    -1

11         0    9    -1    -1

12         0    9    5     -1

13         0    9    5      7 #include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int dp[11][10001];
struct p
{
int money,value;
}nn[11][101];
int main()
{
int n,mm,K,i,j,k;
while(scanf("%d%d%d",&n,&mm,&K)!=EOF)
{
int a,b,c;
int num[15];
memset(num,0,sizeof(num));
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&a,&b,&c);
nn[a][num[a]].money=b;
nn[a][num[a]].value=c;
num[a]++;
}
memset(dp,-1,sizeof(dp));
for(i=0;i<=mm;i++) dp[0][i]=0;
for(k=1;k<=K;k++)
for(i=0;i<num[k];i++)
for(j=mm;j>=nn[k][i].money;j--)
{
if(dp[k][j-nn[k][i].money]!=-1)
dp[k][j]=max(dp[k][j],dp[k][j-nn[k][i].money]+nn[k][i].value);
//更新本行的值,相当于背包
//运行完第一次之后,就会把后面的物品继续放,得到把该类物品放完的最大值
//注意这里的2个if的顺序,如果第二个if在上面的话,当体积为0时,
//相当于,Max( dp[k][j], dp[k][j] + m[k][i].v); dp[k][j]的值很可能会被计算两次。
if(dp[k-1][j-nn[k][i].money]!=-1)
dp[k][j]=max(dp[k][j],dp[k-1][j-nn[k][i].money]+nn[k][i].value);
//每一类的第一个物品,第一个if不会运行,第一次就是保证放一个i类物品
//其次是更新放下该类物品的最大值(一个或多个)
}
if(dp[K][mm]< 0)
printf("Impossible\n");
else
printf("%d\n", dp[K][mm]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: