夏季特惠

凌曦月發表於2020-09-25

題目描述

S t e a m   2019 Steam\ 2019 Steam 2019年夏季促銷開始了!

Y Y Y同學決定⼊⼿⼀些遊戲,⼩Y同學⼀共有 x x x元的預算,該平臺上所有的 n n n個遊戲均有折扣,標號為 i i i的遊戲的原價 a i ai ai元,現價只要 b i bi bi元(也就是說該遊戲可以優惠 a i − b i ai−bi aibi元,每款遊戲最多隻能購買⼀次),並且⼩ Y Y Y同學購買該遊戲能獲得快樂值為 w i wi wi

由於優惠的存在,⼩ Y Y Y作為剁⼿黨可能做出⼀些衝動消費導致最終買遊戲的總費⽤超過預算,但只要滿足獲得的總優惠金額不低於超過預算的總金額,那在⼩ Y Y Y同學⼼理上就不會覺得吃虧(買到就是賺到!真⾹!)。現在⼩Y希望在⼼理上不覺得吃虧的前提下,獲得儘可能多的快樂值。
輸入格式
第⼀⾏包含兩個數 n n n x x x。接下來 n n n⾏包含每個遊戲的資訊,原價 a i ai ai,現價 b i bi bi,能獲得的快樂值為 w i wi wi
輸出格式
輸出⼀個數字,表⽰⼩ Y Y Y同學能獲得的最⼤快樂值。

思路

我們輸入 a i , b i , w i ai,bi,wi ai,bi,wi時。
如果 2 ∗ b i − a i < = 0 2*bi-ai<=0 2biai<=0,這件物品我們就必須要,為什麼?因為我們買了這個物品的話,我們不虧,也就是我們得到的優惠一定大於或等於使用的錢,對後面的選擇完全沒有影響,我們買了的話,有可能會有得賺,何樂而不為呢?

剩下的物品,就直接一個 01 01 01揹包。

程式碼

#include <bits/stdc++.h>
using namespace std;
long long m,n,len,f[1000005],ans;
struct node{ long long y,z; }a[505];

int main() {
	scanf("%lld %lld",&n,&m);
	for(long long i=1,ai,bi,ci;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(long long i=1;i<=len;i++) {
		for(long long j=m;j>=a[i].y;j--) {
			if(f[j-a[i].y]+a[i].z>f[j])
				f[j]=f[j-a[i].y]+a[i].z;			
		}
	}
	printf("%lld",f[m]+ans);
	return 0;
}

相關文章