专题三1024

题目大意:

第一行输入两个整数,第一个是物品的种类的数量N,第二个是你手里持有的钱数M,然后底下再输入N行,每行包括3个整数p(物品的标价),q(买这一件商品你手里需要的最少钱数),v(这件商品能带给你的价值)。编程输出在手里持有钱数的范围内,即在经济范围内买的东西的最大价值。

解题思路:

乍一看这道题觉得像是一道01背包,其实这道题勉强可以说是一道01背包的问题。但是01背包问题与物品的顺序无关,而这个问题的答案与购买物品的顺序有着莫大的关系。买一件东西的时候能否可以买取决于手中持有的钱数,而这钱数并不是是否大于等于这件商品的价格,这个钱数要远大于商品的价格。这就牵扯到给物品的排序问题,而排序的依据呢????我就是以q-p的差价作为排序的标准来给物品排序,这样就是一道01背包问题,能用手里的钱买到最大价值的东西。01背包的状态转移方程:bag[j]=max(bag[j],bag[j-cos[i]]+val[i])

代码如下:

#include<stdio.h>

#include <iostream>

#include <algorithm>

using namespace std;

#define max(a,b) (a>b?a:b)

struct Shopping

{

int price;

int least;

int desert;

};

int cmp(Shopping a, Shopping b)

{

return (a.least - a.price)<(b.least - b.price);

}

int main()

{

int bag[5001];

Shopping sp[5001];

int number, money;

while (cin >> number)

{

cin >> money;

for (int i = 1; i <= number; i++)

{

cin >> sp[i].price;

cin >> sp[i].least;

cin >> sp[i].desert;

}

memset(bag, 0, sizeof(bag));

sort(sp + 1, sp + number + 1, cmp);

for (int i = 1; i <= number; i++)

{

for (int j = money; j >= sp[i].least; j--)

{

bag[j] = max(bag[j], bag[j - sp[i].price] + sp[i].desert);

}

}

cout << bag[money] << endl;

}

return 0;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值