BZOJ 2667 cqoi2012 模拟工厂 贪心

题目大意:现在你有一个工厂,初始生产力为1,每一时刻你可以进行如下操作:

1.将生产力提高1

2.生产一些产品,数量等于当前生产力的数值

现在你有n个订单,每一份有一个交易时间t,一个商品数量g和一个价格m,可以接或者不接,如果接就要在t时刻操作之前减少g的商品数量,然后得到m的钱

求最大收益

跪shanest大爷。。。

由于n≤15,爆枚接受哪些订单

每次Check的时候,对于每段时间显然先提高生产力再生产产品

那么我可以考虑这一段内先尽量提高生产力 但是这样可能会导致生产力提高得太高而没有足够的时间生产产品使得某个订单失败

因此我们计算出对于后面的每一个订单,最多花多少时间提高生产力可以满足如果用接下来的时间都生产的话不至于fail

由于产品数量是关于提高生产力次数的二次函数 因此解个方程就行了

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 20
using namespace std;

struct abcd{
    int tim,goods,money;
    friend istream& operator >> (istream &_,abcd &a)
    {
        return scanf("%d%d%d",&a.tim,&a.goods,&a.money),_;
    }
    bool operator < (const abcd &a) const
    {
        return tim < a.tim ;
    }
}a[M],stack[M];

int n,top;
long long ans;

int Calculate(long long k,long long t,long long g)
{
    long long a=1,b=k-t,c=g-k*t;
    long long delta=b*b-4*a*c;
    if(delta<0)
        return -1;
    return (long long)(floor( (-b+sqrt(delta))/2/a +1e-7 )+1e-7);
}

bool Judge()
{
    int i,j;
    long long productivity=1,_goods=0;
    for(i=1;i<=top;i++)
    {
        long long sum=0;
        int _tim=stack[i].tim-stack[i-1].tim;
        for(j=i;j<=top;j++)
        {
            sum+=stack[j].goods;
            if(sum>_goods)
                _tim=min(_tim, Calculate(productivity,stack[j].tim-stack[i-1].tim,sum-_goods) );
        }
        if(_tim<0)
            return false;
        productivity+=_tim;
        _goods+=productivity*(stack[i].tim-stack[i-1].tim-_tim);
        _goods-=stack[i].goods;
    }
    return true;
}

int main()
{
    int i,j;
    cin>>n;
    for(i=1;i<=n;i++)
        cin>>a[i];
    sort(a+1,a+n+1);
    for(i=1;i<1<<n;i++)
    {
        long long _money=0;
        top=0;
        for(j=1;j<=n;j++)
            if(i&(1<<j-1))
                stack[++top]=a[j],_money+=a[j].money;
        if( Judge() )
            ans=max(ans,_money);
    }
    cout<<ans<<endl;
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-17 05:55:14

BZOJ 2667 cqoi2012 模拟工厂 贪心的相关文章

LUOGU P3161 [CQOI2012]模拟工厂 (贪心)

传送门 解题思路 贪心,首先因为\(n\)比较小,可以\(2^n\)枚举子集.然后判断的时候就每次看后面的如果用最大生产力生产能不能达成目标,解一个二次函数. 代码 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define int long long using namespace std; const int

[BZOJ2667][cqoi2012]模拟工厂

试题描述 有一个称为"模拟工厂"的游戏是这样的:在时刻0,工厂的生产力等于1.在每个时刻,你可以提高生产力或者生产商品.如果选择提高生产力,在下一个时刻时工厂的生产力加1:如果选择生产商品,则下一个时刻你所拥有的商品数量增加p,其中p是本时刻工厂的生产力. 有n个订单,可以选择接受或者不接受.第i个订单(ti, gi, mi)要求在时刻ti给买家提供gi个商品,事成之后商品数量减少gi,而收入增加mi元.如果接受订单i,则必须恰好在时刻ti交易,不能早也不能晚.同一时刻可以接受多个订单

[BZOJ2667][cqoi2012][kcoj]模拟工厂

题目描述 Description 有一个称为"模拟工厂"的游戏是这样的:在时刻0,工厂的生产力等于1.在每个时刻,你可以提高生产力或者生产商品.如果选择提高生产力,在下一个时刻时工厂的生产力加1:如果选择生产商品,则下一个时刻你所拥有的商品数量增加p,其中p是本时刻工厂的生产力. 有n个订单,可以选择接受或者不接受.第i个订单(ti, gi, mi)要求在时刻ti给买家提供gi个商品,事成之后商品数量减少gi,而收入增加mi元.如果接受订单i,则必须恰好在时刻ti交易,不能早也不能晚.

BZOJ 2666 cqoi2012 组装 贪心

题目大意:给定数轴上的m个点,共有n种颜色,要求在数轴上选定一个点,使这个点到每种颜色最近的点的平方和最小 初始将所有颜色最左侧的点作为最近点,然后不断选择[当前点与同种颜色下一个点的中点最靠左的点]进行替换,并更新ans 理性证明见http://www.cnblogs.com/jianglangcaijin/p/4204478.html 下面来个感性证明: 这不是显然么- - 考虑将组装车间从-∞移动到+∞ 初始选择最左侧的点作为最近点 那么移动的过程中一旦车间离同种颜色的下一个点更近 那么当

POJ 1696 Space Ant --枚举,模拟,贪心,几何

题意: 有很多点,从最右下角的点开始走起,初始方向水平向右,然后以后每步只能向左边走,问最多能走多少个点. 解法: 贪心的搞的话,肯定每次选左边的与它夹角最小的点,然后走过去. 然后就是相当于模拟地去选点,然后计数,然后走过去.这题就这么搞定了. 我这里用了set和vector. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include &

BZOJ 1029 建筑抢修(贪心堆)

原题代号:BZOJ 1029 原题描述: 建筑抢修 小刚在玩JSOI提供的一个称之为"建筑抢修"的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建筑设施将会完全毁坏.现在的情况是:T部落基地里只有一个修理工人,虽然他能瞬间到达任何一个建筑,但是修复每个建筑都需要一定的时间.同时,修理工人修理完一个建筑才能修理下一个建筑,不能同时修理多个建筑.如果某个建筑在一段时间之内没有完全修理完毕,这个建

BZOJ 1088 水模拟

BZOJ水一道~ 枚举前两个位置是否放雷,模拟向下推.能够则ans++ #include "stdio.h" #include "string.h" int a[10010],b[10010],n; int judge() { int i; for (i=3;i<=n;i++) { b[i]=a[i-1]-b[i-1]-b[i-2]; if (b[i]<0) return 0; if (b[i]>1) return 0; } if (b[n-1]+

CodeForces 342B Xenia and Spies (水题模拟,贪心)

题意:给定 n 个间谍,m个区间,一个 s,一个f,然后从 s开始传纸条,然后传到 f,然后在每个 t 时间在区间内的不能传,问你最少的时间传过去. 析:这个题,就模拟一下就好,贪心策略,能传就传,找好方向,一直传就行,传到 f 就结束. 代码如下: #include <bits/stdc++.h> using namespace std; struct node{ int l, r, t; bool operator < (const node &p) const{ retur

BZOJ 1029: [JSOI2007]建筑抢修 贪心

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1029 小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建筑设施将会完全毁坏.现在的情况是:T部落基地里只有一个修理工人,虽然他能瞬间到达任何一个建筑,但是修复每个建筑都需要一定的时间.同时,修理工人修理完一个建筑才能修理下一个建筑,不能同时修理多个建