2667: [cqoi2012]模拟工厂

来源:互联网 发布:数据分析在职研究生 编辑:程序博客网 时间:2024/06/05 19:16

题目链接

题目大意:现在你有一个工厂,初始生产力为1,每一时刻你可以进行如下操作:
1.将生产力提高1
2.生产一些产品,数量等于当前生产力的数值
然后你有n个订单,每一份有一个交易时间t,一个商品数量g和一个价格m,可以接或者不接,如果接就要在t时刻操作之前减少g的商品数量,然后得到m的钱
求最大收益

题解:n很小,暴力枚举接受的订单
aq=qi=1gi
qtq使aq

贪心:如果有t天,x天提升生产力,那么先提升生产力较优
s(s+x)(tx)aqnowhave

x=minnj=iri

Orz

我的收获:强啊,方程思想

#include <cstdio> #include <iostream>#include <cstdlib>  #include <algorithm>  #include <cmath>  using namespace std;typedef long long ll;  const int M=25;  int n,tot;ll ans,tmp; ll w,sumg,t,x;struct abcd{      ll t,g,m;      void read(){scanf("%lld%lld%lld",&t,&g,&m);}}s[M],a[M];bool operator <(abcd x,abcd y){return x.t<y.t;} inline ll Calc(double a,double b,double c){      double delta=b*b-4*a*c;      if(delta<0) return -1;      double x1,x2;      x1=(-b-sqrt(delta))/a/2; x2=(-b+sqrt(delta))/a/2;      if(x1>x2) swap(x1,x2);      return floor(x2);}  inline bool judce()  {      w=1;sumg=0;      for(int i=1;i<=tot;i++)      {          x=t=a[i].t-a[i-1].t;          ll now=0;          for(int j=i;j<=tot;j++)          {              now+=a[j].g;              if(now>sumg)                  x=min(x,Calc(-1,(a[j].t-a[i-1].t)-w,(a[j].t-a[i-1].t)*w+sumg-now));          }          if(x<0) return 0;          sumg+=(w+=x)*(t-x);          sumg-=a[i].g;      }      return 1;  }  void work(){    for(int i=0;i<(1<<n);i++)      {          tmp=tot=0;          for(int j=1;j<=n;j++)              if(i&(1<<(j-1)))                  tmp+=s[j].m,a[++tot]=s[j];//找到接的订单         if (judce()) ans=max(ans,tmp);      }      printf("%lld\n",ans);  }void init(){    cin>>n;    for(int i=1;i<=n;i++) s[i].read();     sort(s+1,s+n+1); }int main()  {      init();      work();    return 0;}  
原创粉丝点击