zoukankan      html  css  js  c++  java
  • [BZOJ2667][cqoi2012]模拟工厂 贪心

    2667: [cqoi2012]模拟工厂

    Time Limit: 3 Sec  Memory Limit: 128 MB
    Submit: 367  Solved: 184
    [Submit][Status][Discuss]

    Description

    有一个称为“模拟工厂”的游戏是这样的:在时刻0,工厂的生产力等于1。在每个时刻,你可以提高生产力或者生产商品。如果选择提高生产力,在下一个时刻时工厂的生产力加1;如果选择生产商品,则下一个时刻你所拥有的商品数量增加p,其中p是本时刻工厂的生产力。
    n个订单,可以选择接受或者不接受。第i个订单(tigimi)要求在时刻ti给买家提供gi个商品,事成之后商品数量减少gi,而收入增加mi元。如果接受订单i,则必须恰好在时刻ti交易,不能早也不能晚。同一时刻可以接受多个订单,但每个订单只能被接受一次。要求最后的总收入最大。
    例如,如果一共有两个订单(5,1,8)和(7,15,3),用如下策略是最优的:时刻0, 1, 2提高生产力(时刻3的生产力为4),然后在时刻3,4生产商品,则在时刻5时将拥有8个商品。此时接受第1个订单(还会剩下7个商品),并且在时刻5,6继续生产商品,则在时刻7时拥有7+4+4=15个商品,正好满足订单2。

    Input

    输入第一行包含一个整数n,即订单数目。以下n行每行三个整数tigimi
     

    Output

     
    输出仅一行,为最大总收入。输出保证在32位带符号整数范围内。

    Sample Input

    2
    5 1 8
    7 15 3

    Sample Output

    11

    HINT




































    编号


    1-3


    4-6


    7-10


    n


    <=5


    <=10


    <=15


    ti


    100


    100


    <=100,000


    gi


    10,000


    10,000


    <=109


    mi


    10,000


    10,000


    <=109

    Source

    考虑贪心,显然每一段先加生产力再生产。

    枚举订单后n*n check。

    check时我们设当前工作力为g,天数为t,现在剩余a

    则得方程(g+x)(t-x)>=a+需求。可解出能够增加生产力的天数。

    联立方程,可得若干个区间[l,r]。显然取最小的r作为增加生产力的天数。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #define ll long long
     8 using namespace std;
     9 ll n;
    10 struct data {
    11     ll tim,g,m;
    12     bool operator <(const data tmp)const {
    13         return tim<tmp.tim;
    14     }
    15 }t[20];
    16 int q[20],tot;
    17 ll gets(ll a,ll b,ll c) {
    18     ll de=b*b-4*a*c;if(de<0) return -1;
    19     double d=sqrt(de);
    20     double x1=(-b-d)/(2.0*a),x2=(-b+d)/(2.0*a);
    21     return max((ll)floor(x1),(ll)floor(x2));
    22 }
    23 ll ans=0;
    24 void solve(int x) {
    25     ll sum=0;tot=0;
    26     for(int i=1;i<=n;i++) if((1<<(i-1))&x) q[++tot]=i; 
    27     ll s=0,g=1;
    28     for(int i=1;i<=tot;i++) {
    29         ll tmp=2147483647ll,now=0;
    30         for(int j=i;j<=tot;j++) {
    31             now+=t[q[j]].g;
    32             ll b=t[q[j]].tim-t[q[i-1]].tim;
    33             tmp=min(tmp,gets(-1,b-g,b*g+s-now));
    34             if(tmp<0) {sum=0;return;}
    35         }
    36         g+=tmp;s+=g*(t[q[i]].tim-t[q[i-1]].tim-tmp);sum+=t[q[i]].m;s-=t[q[i]].g;
    37     }
    38     ans=max(ans,sum);
    39 }
    40 int main() {
    41     scanf("%lld",&n);
    42     for(int i=1;i<=n;i++) scanf("%lld%lld%lld",&t[i].tim,&t[i].g,&t[i].m);
    43     sort(t+1,t+n+1);
    44     for(int i=0;i<=(1<<n)-1;i++) solve(i);
    45     printf("%lld",ans);
    46 }
    View Code
    O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~
  • 相关阅读:
    UITextField最大字符数和最大字节数的限制
    Python profiling
    Glow Android 优化实践
    当 NSDictionary 遇见 nil
    TCP/IP详解2 学习笔记---mbuf
    行业代码获取最近代码
    词语、句子相似度比较
    从word得到表格数据插入数据库(6位行业代码)
    python遍历数组获取下标
    计算机浮点数表示
  • 原文地址:https://www.cnblogs.com/wls001/p/8435093.html
Copyright © 2011-2022 走看看