这是一道水题,板的不能再板。
题目描述
Steam2019年夏季促销开始了!
⼩Y同学决定⼊⼿⼀些游戏,⼩Y同学⼀共有x元的预算,该平台上所有的n个游戏均有折扣,标号为i的游戏的原价ai元,现价只要bi元(也就是说该游戏可以优惠ai−bi元,每款游戏最多只能购买⼀次),并且⼩Y同学购买该游戏能获得快乐值为wi。
由于优惠的存在,⼩Y作为剁⼿党可能做出⼀些冲动消费导致最终买游戏的总费⽤超过预算,但只要满足获得的总优惠金额不低于超过预算的总金额,那在⼩Y同学⼼理上就不会觉得吃亏(买到就是赚到!真⾹!)。现在⼩Y希望在⼼理上不觉得吃亏的前提下,获得尽可能多的快乐值。
输入格式
第⼀⾏包含两个数n和x。接下来n⾏包含每个游戏的信息,原价ai,现价bi,能获得的快乐值为wi。
输出格式
输出⼀个数字,表⽰⼩Y同学能获得的最⼤快乐值
样例
样例输入1:
4 100
100 73 60
100 89 35
30 21 30
10 8 10
样例输出1:
100
样例输入2:
3 100
100 100 60
80 80 35
21 21 30
样例输出2:
60
样例输入3:
2 100
100 30 35
140 140 100
样例输出3:
135
首先一眼看出背包dp,与板子唯一的不同就在于有快乐值的存在。
让我们推一推:
设第i个原价ai,现价bi,快乐值wi,则花费(相当于体积)为
bi - (ai - bi) 即 2 * bi - ai
快乐值(价值)为wi
然后有一种特殊情况:2 * bi - ai < 0
就是买这个不但不花钱,反而还赚钱。我们直接在输入时先放进背包(何乐而不为)
亮代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cctype>
#include<iomanip>
using namespace std;
const int M=1e6+5;
int m,n,len;
long long ai,bi,ci,dp[M],ans;
struct node{
long long y,z;
};
node a[505];
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%lld %lld %lld",&ai,&bi,&ci);
long long vi=bi*2-ai;
if(vi<=0)
m-=vi,ans+=ci;
else
a[++len].y=vi,a[len].z=ci;
}
for(int i=1;i<=len;i++)
for(int j=m;j>=a[i].y;j--)
dp[j]=max(dp[j-a[i].y]+a[i].z,dp[j]);
printf("%lld\n",dp[m]+ans);
return 0;
}
谢谢大家