题意
有n种食材,每种食材有三个属性,ai,bi和ci,如果在t时刻完成第i样食材则得到ai-t*bi的美味指数,用第i件食材做饭要花去ci的时间。问在T时间内,什么样的烹调方案使得美味指数最大,输出最大的美味指数
解题思路
简单看来,这就是一个01背包问题,但是不同之处在于这里每个食材的价值会因为时间而改变,所以对于每个时间点,我们需要考虑此时先选择哪一种食材
记now为当前时间,食材1的属性:a1,b1,c1,食材2的属性:a2,b2,c2
1)先选择食材1的总价值:a1 - (now + c1) * b1 + a2 - (now + c1 + c2 ) * b2;
2)先选择食材2的总价值:a2 - (now + c2) * b2 + a1 - (now + c1 + c2 ) * b1
两者比较一下,发现当 c1 * b2 < c2 * b1 的时候,先选取食材1的价值更大,那么我们就将n种食材按照这样的方式排序,随后就是01背包处理了
代码区
#include<iostream> #include<cstdio> #include<algorithm> #define LOCAL = 1; using namespace std; typedef long long ll; const int Max = 1e5 + 10; struct Node { ll a, b, c; } node[55]; int v, n; ll dp[Max]; //记录在第i时刻的最大价值 bool cmp(Node x, Node y) { return x.c * y.b < y.c * x.b; } int main() { #ifdef LOCAL // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); #endif scanf("%d%d", &v, &n); for (int i = 1; i <= n; i++) scanf("%lld", &node[i].a); for (int i = 1; i <= n; i++) scanf("%lld", &node[i].b); for (int i = 1; i <= n; i++) scanf("%lld", &node[i].c); sort(node + 1, node + 1 + n,cmp); for (int i = 1; i <= n; i++) { for (int j = v; j >= node[i].c; j--) { dp[j] = max(dp[j], dp[j - node[i].c] + node[i].a - j * node[i].b); } } ll max_val = 0; for (int j = 1; j <= v; j++) { max_val = max(dp[j], max_val); } printf("%lld\n", max_val); return 0; }
原文地址:https://www.cnblogs.com/winter-bamboo/p/11478252.html
时间: 2024-10-09 17:30:21