• 烹调方案 (公式,DP,背包)


    烹调方案

    题目链接

    题目

    一共有n件食材,每件食材有三个属性,ai,bi和ci,如果在t时刻完成第i样食材则得到ai-t*bi的美味指数,用第i件食材做饭要花去ci的时间。

    众所周知,gw的厨艺不怎么样,所以他需要你设计烹调方案使得美味指数最大。

    【数据范围】

    对于40%的数据1<=n<=10

    对于100%的数据1<=n<=50

    所有数字均小于100,000

    分析

    这道题可以看到背包的影子,但是不同的是价值会不断变化。
    所以我们可以尝试推一下式子 (由这道题我们可以看出推式子的重要性
    (x, y) 为相邻的两件物品,分别列出先取x 和 先取y的价值 :
    (f[x] = a[x] - t * b[x] + a[y] - (t + c[x]) * b[y])
    (f[y] = a[y] - t * b[y] + a[x] - (t + c[y]) * b[x])
    可以发现 (f[x] > f[y]) 时当且仅当 (c[x] * b[y] < c[y] * b[x])
    由此我们可以排下序,然后跑一个裸的 01 背包。

    代码

    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    struct node { int a, b, c; } e[55];
    int f[100005], Max = -0x3f3f3f3f, n, m;
    bool cmp(node u, node v) { return u.c * v.b < u.b * v.c; }
    signed main() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        cin >> m >> n;
        for(int i = 1; i <= n; ++i) cin >> e[i].a;
        for(int i = 1; i <= n; ++i) cin >> e[i].b;
        for(int i = 1; i <= n; ++i) cin >> e[i].c;
        sort(e + 1, e + n + 1, cmp);
        for(int i = 1; i <= n; ++i) {
            for(int j = m; j >= e[i].c; --j) {
                f[j] = max(f[j], f[j - e[i].c] + e[i].a - j*e[i].b);
                Max = max(Max, f[j]); 
            }
        }
        cout << Max;
        return 0;
    }
    

    别忘了开 long long (有可能是负数)。

  • 相关阅读:
    Vue内置指令
    Vue计算属性
    Ubuntu下编译Bilibili/ijkplayer
    自毁程序
    Android最大可运行内存
    Android ListView onItemClick Not Work
    Java/Android 二进制数据与String互转
    JAVA/Android Map与String的转换方法
    java中打印变量地址
    Win7 关闭Window update
  • 原文地址:https://www.cnblogs.com/DZN2004/p/13401691.html
Copyright © 2020-2023  润新知