天天看點

三分 - HNU 13409 Flowers  http://acm.hnu.cn/online/?action=problem&type=show&id=13409&courseid=0

Flowers 

Problem's Link:  http://acm.hnu.cn/online/?action=problem&type=show&id=13409&courseid=0

Mean: 

有N顆種子,每顆種子初始時營養值為0。當一顆種子營養值達到th後就會開花。

有兩種操作:

1.給所有的種子澆w升水;

2.給某個種子施f升肥;

對于第i顆種子,每澆1升水會增加vw點營養值,每施1升肥可以增加vf點營養值,該種種子的肥料單價為pf,當營養值達到th後開花。

澆水必須一起澆,而且水的單價是一樣的,都是pw。花的th可能為負,而且有的花澆水營養值會減少。

analyse:

很明顯的凸函數。

由于澆水的量所有種子都相同,是以三分水量即可。

Time complexity: O(N)

Source code: 

/*

* this code is made by crazyacking

* Verdict: Accepted

* Submission Date: 2015-08-16-19.52

* Time: 0MS

* Memory: 137KB

*/

#include <queue>

#include <cstdio>

#include <set>

#include <string>

#include <stack>

#include <cmath>

#include <climits>

#include <map>

#include <cstdlib>

#include <iostream>

#include <vector>

#include <algorithm>

#include <cstring>

#define eps 1e-14

#define  LL __int64

#define  ULL unsigned __int64

using namespace std;

const int MAXN=10+(int)1e5;

LL n,pw,vw[MAXN],pf[MAXN],vf[MAXN],th[MAXN];

double tmp,t;

double cal(double& w)

{

     tmp=w*pw;

     for(int i=0;i<n;++i)

     {

           t=th[i]-w*vw[i];

           if(t<=0) continue;

           tmp+=(t)*pf[i]*1./vf[i];

     }

     return tmp;

}

double work(double l,double r)

     double mid,mmid;

     int st=100;

     while(st--)

           mid=(l+r)/2;

           mmid=(mid+r)/2;

           if(cal(mid)-cal(mmid)>eps)

                 l=mid;

           else r=mmid;

     return l;

int main()

     ios_base::sync_with_stdio(false);

     cin.tie(0);

     while(scanf("%I64d",&n),n)

           scanf("%I64d",&pw);

           for(int i=0;i<n;++i)

           {

                 scanf("%I64d %I64d %I64d %I64d",&vw[i],&pf[i],&vf[i],&th[i]);

           }

           double val=work(0,200);

           printf("%.6lf\n",cal(val));

     return 0;

      |  Github |  Facebook  |  Twitter |