zoukankan      html  css  js  c++  java
  • [luoguP1417] 烹调方案(背包DP)

    传送门

    By tinylic

    如果没有b[i]这个属性的话就是明显的01背包问题。

    现在考虑相邻的两个物品x,y。假设现在已经耗费p的时间,那么分别列出先做x,y的代价:

    a[x]-(p+c[x])*b[x]+a[y]-(p+c[x]+c[y])*by

    a[y]-(p+c[y])*b[y]+a[x]-(p+c[y]+c[x])*bx

    对这两个式子化简,得到①>②的条件是c[x]*b[y]<c[y]*b[x].

    发现只要满足这个条件的物品对(x,y),x在y前的代价永远更优。

    因此可以根据这个条件进行排序,之后就是简单的01背包了。

    然而我看这个DP方程还不是完全的01背包,应该是 f[i] 表示到时刻 i 的最优解,且时刻 i 必须得用

    代码

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #define N 100001
    #define LL long long
    #define max(x, y) ((x) > (y) ? (x) : (y))
    
    int T, n;
    LL ans, f[N];
    
    struct node
    {
        LL a, b, c;
    }p[51];
    
    inline int read()
    {
        int x = 0, f = 1;
        char ch = getchar();
        for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
        for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
        return x * f;
    }
    
    inline bool cmp(node x, node y)
    {
        return x.c * y.b < y.c * x.b;
    }
    
    int main()
    {
        int i, j;
        T = read();
        n = read();
        for(i = 1; i <= n; i++) p[i].a = read();
        for(i = 1; i <= n; i++) p[i].b = read();
        for(i = 1; i <= n; i++) p[i].c = read();
        std::sort(p + 1, p + n + 1, cmp);
        for(i = 1; i <= n; i++)
            for(j = T; j >= p[i].c; j--)
            {
                f[j] = max(f[j], f[j - p[i].c] + p[i].a - j * p[i].b);
                ans = max(ans, f[j]);
            }
        printf("%lld
    ", ans);
        return 0;
    }
    

      

  • 相关阅读:
    网络密钥交换协议——Diffie-Hellman
    【剑指Offer】俯视50题之1-10题
    分治
    《Java程序猿面试笔试宝典》之Java程序初始化的顺序是如何的
    China Final J
    MVC入门
    1,单例模式
    运行耗时统计
    普通方法调用,Invoke,begininvoke三者的区别总结及异步与同步的区别总结
    几种查询方法(lambda Linq Enumerable静态类方式)
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/7061403.html
Copyright © 2011-2022 走看看