题目背景
由于你的帮助,火星只遭受了最小的损失。但gw懒得重建家园了,就造了一艘飞船飞向遥远的earth星。不过飞船飞到一半,gw发现了一个很严重的问题:肚子饿了~
gw还是会做饭的,于是拿出了储藏的食物准备填饱肚子。gw希望能在T时间内做出最美味的食物,但是这些食物美味程度的计算方式比较奇葩,于是绝望的gw只好求助于你了。
题目描述
一共有n件食材,每件食材有三个属性,ai,bi和ci,如果在t时刻完成第i样食材则得到ai-t*bi的美味指数,用第i件食材做饭要花去ci的时间。
众所周知,gw的厨艺不怎么样,所以他需要你设计烹调方案使得美味指数最大
输入输出格式
输入格式:
第一行是两个正整数T和n,表示到达地球所需时间和食材个数。
下面一行n个整数,ai
下面一行n个整数,bi
下面一行n个整数,ci
输出格式:
输出最大美味指数
输入输出样例
输入样例#1:
74 1
502
2
47
输出样例#1:
408
解题思路
一般的01背包,由于价值是固定不变的,所以顺序对结果不影响,但是这道题它的价值却不是固定的,所以首先需要排序;
1)式:a[x] - (p+c[x]) * b[x] + a[y] - (p+c[x]+c[y]) * b[y]
2)式:a[y] - (p+c[y]) * b[y] + a[x] - (p+c[y]+c[x]) * b[x]
由 1) > 2) 可得:c[x] * b[y] < c[y] * b[x]
代码如下
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 typedef long long ll; 5 struct node{ 6 ll a, b, c; 7 }t[100100]; 8 ll dp[100100]; 9 bool cmp(node &x, node &y){ 10 return x.c * y.b < y.c * x.b; 11 } 12 int main(){ 13 ll time, n; 14 cin >> time >> n; 15 for(ll i = 1; i <= n; i++) cin >> t[i].a; 16 for(ll i = 1; i <= n; i++) cin >> t[i].b; 17 for(ll i = 1; i <= n; i++) cin >> t[i].c; 18 sort(t + 1, t + n + 1, cmp); 19 for(ll i = 1; i <= n; i++){ 20 for(ll j = time; j >= t[i].c; j--){ 21 dp[j] = max(dp[j], dp[j - t[i].c] + t[i].a - j * t[i].b); 22 } 23 } 24 ll maxn = -1; 25 for(ll i = 0; i <= time; i++){ 26 maxn = max(maxn, dp[i]); 27 } 28 cout << maxn << endl; 29 return 0; 30 }
注意点
答案不一定是f[time]