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

本文详细介绍了如何使用动态规划解决HDU在线评测平台3033题,该题涉及背包问题。通过阅读本文,读者可以掌握背包问题的基本解决策略,并了解如何应用动态规划算法来求解此类问题。

题目链接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
           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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值