• P1417 烹调方案


    传送门

    思路:

      可以用 01 背包做,但是如果直接套用 01背包 模板就 GG 了。因为随着时间的推移,每个物品的价值在不断的发生改变。

      现在考虑相邻的两个物品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背包了。

                                         ——参考 kkksc03

    标程:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<cstdlib>
    #include<stack>
    #include<vector>
    #include<queue>
    #include<deque>
    #include<map>
    #include<set>
    using namespace std;
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define maxn 51
    typedef long long LL;
    LL T,n,ans=-0x3f;
    LL f[maxn][100001];
    struct hh
    {
        LL ai,bi,ci;
    }t[maxn];
    inline LL read()
    {
        LL kr=1,xs=0;
        char ls;
        ls=getchar();
        while(!isdigit(ls))
        {
            if(!(ls^45))
                kr=-1;
            ls=getchar();
        }
        while(isdigit(ls))
        {
            xs=(xs<<1)+(xs<<3)+(ls^48);
            ls=getchar();
        }
        return xs*kr;
    }
    inline bool cmp(const hh&a,const hh&b)
    {
        return a.ci*b.bi<b.ci*a.bi;
    }
    int main()
    {
        T=read();n=read();
        for(LL i=1;i<=n;i++)
            t[i].ai=read();
        for(LL i=1;i<=n;i++)
            t[i].bi=read();
        for(LL i=1;i<=n;i++)
            t[i].ci=read();
        sort(t+1,t+n+1,cmp);
        for(LL i=1;i<=n;i++)
        {
            for(LL j=T;j>=0;j--)
            {
                if(t[i].ci<=j)
                {
                    f[i][j]=max(f[i-1][j],f[i-1][j-t[i].ci]+t[i].ai-j*t[i].bi);
                }
                else f[i][j]=max(f[i][j],f[i-1][j]);
            }
        }
        for(LL i=1;i<=T;i++)
            ans=max(ans,f[n][i]);
        printf("%lld
    ",ans);
    return 0;
    }
  • 相关阅读:
    Codeforces 831 A Unimodal Array 模拟(我感觉我现在比任何时候都理解程序员就是专门写各种Bug这句话)
    HDU 1205 吃糖果 鸽巢原理
    UVA 12716 GCDXOR 数论
    HDU 6152 Friend-Graph Ramsey定理 组合数学
    UVA 10791 Minimum Sum LCM 数论
    DFS系列 POJ(自认为的讲解)
    HDU 5101
    gets,gets_s,fgets函数
    vector理解一波~~~
    BestCoder Round #74 (div.1) 1002Shortest Path(hdoj5636)
  • 原文地址:https://www.cnblogs.com/lck-lck/p/9800103.html
Copyright © 2020-2023  润新知