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;
View Code

以上是关于P1417 烹调方案(思维+01背包)的主要内容,如果未能解决你的问题,请参考以下文章

P1417 烹调方案

P1417 烹调方案//基础背包 卡longlong

P1417 烹调方案 背包DP

洛谷 P1417烹调方案

P1417 烹调方案

P1417 烹调方案