P1417 烹调方案(思维+01背包)
Posted winter-bamboo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1417 烹调方案(思维+01背包)相关的知识,希望对你有一定的参考价值。
题意
有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;
以上是关于P1417 烹调方案(思维+01背包)的主要内容,如果未能解决你的问题,请参考以下文章