hdu 3033 I love sneakers!

本来想着早起一水的。。。结果拖到现在才解决。。。题意是有k种鞋子, 每种鞋子有num种,每种都有其价格和value。要求给定m块钱,每种鞋子至少买一种,求最大的value值,不能满足则输出“Impossible”。

算是背包变形吧。想了很久,觉得就要接近正确思想了,但是每种鞋子至少买一种那部分不知道怎么搞,刚开始写了个枚举每一种鞋子第i种必买,然后对剩下的做01背包的程序,无奈sample都过不了。。。弱爆了。。。

于是猫了一眼网上的题解,由于这题自己思考了很久了,一看题解便顿悟了。。用结构体二位数组g[i][j]保存第i种鞋子的第j种型号的信息。dp[i][j]表示购买前i种鞋子,花费j块钱得到得最大value值,那么对于g[i][j]鞋子,有两种状态,要么从上组中继承过来,要么从这一组的前面继承过来,前提是上一种状态可到达(解决每种至少买一个)。状态转移是不难的。。。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn =  100001;
struct SHOES
{
    int v, w;
}g[11][111];
int n, m, k, num[11], dp[11][maxn];

int main()
{
    while(~scanf("%d%d%d", &n, &m, &k))
    {
        memset(dp, -1, sizeof(dp));
        memset(dp[0], 0, sizeof(dp[0]));
        memset(num, 0, sizeof(num));
        
        int a, b, c;
        for(int i=0; i<n; i++)
        {
            scanf("%d%d%d", &a, &b, &c);
            g[a][num[a]].v = b;
            g[a][num[a]++].w = c;
        }
        
        for(int i=1; i<=k; i++)
        {
            for(int j=0; j<num[i]; j++)
            {
                for(int V=m; V>=g[i][j].v; V--)
                {
                    if(dp[i][V-g[i][j].v] != -1) //从第i种鞋子前面继承并且可到达
                        dp[i][V] = max(dp[i][V], dp[i][V-g[i][j].v] + g[i][j].w);
                    if(dp[i-1][V-g[i][j].v] != -1)  //从第i-1种鞋子继承并且可到达
                        dp[i][V] = max(dp[i][V], dp[i-1][V-g[i][j].v] + g[i][j].w);
                }
            }
        }
        if(dp[k][m] < 0)    puts("Impossible");
        else    printf("%d\n", dp[k][m]);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值