【noip 1999】旅行家的预算

来源:互联网 发布:美国非农数据公布网站 编辑:程序博客网 时间:2024/04/30 20:51

去题面的传送门
贪心
从当前位置查找可以到达的最大范围内,最近的价格小于当前价格的站点。如果没有,就在当前站加满油,一直走到不能走到下一个加油站为止。直到到达终点。
一开始想的贪心是如果没有比它小的,就在可到达范围内找一个最小的,到那个站去加油。但是这样肯定不是最优的,既然找不到,那我们就在当前便宜的站点尽可能多地加油。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=100+10;double D1,D2,C,P,ans,need;int cnt,Ans[maxn],N;bool bo=0,f=0;struct hh{    double di,pi;}e[maxn];bool cmp(hh x,hh y){    return x.di<y.di;}void done(){    e[0].pi=P;    e[0].di=0;    e[N+1].di=D1;    int now=0,last;    double have=0;    while(now<=N)    {        bool flg=0,bo=0;        for(int i=now+1;i<=N;++i)        {            if(e[i].pi<e[now].pi)            {              bo=1;              if(e[i].di-e[now].di<=need)               {                 ans+=(e[i].di-e[now].di)/D2*e[now].pi;                have=0;                now=i;                last=i;              }              else flg=1;              break;          }         }          if(flg||!bo)        {            if(D1-e[now].di<=need) break;            ans+=(C-have)*e[now].pi;            int i=now+1;            for(i=now+1;i<=N+1;++i)              if(e[i].di-e[now].di>need) break;            i--;            have=C-(e[i].di-e[now].di)/D2;            now=i;            last=i;        }    }    ans+=((D1-e[last].di)/D2-have)*e[last].pi;}int main(){    scanf("%lf%lf%lf%lf%d",&D1,&C,&D2,&P,&N);    need=D2*C;    for(int i=1;i<=N;++i) scanf("%lf%lf",&e[i].di,&e[i].pi);    sort(e+1,e+N+1,cmp);    e[0].di=0;    for(int i=1;i<=N;++i)      if(e[i].di-e[i-1].di>need) f=1;    if(D1-e[N].di>D2*C) f=1;        ans=0.00;    if(f)     {        printf("No Solution");        return 0;    }    done();    printf("%.2lf",ans);    return 0;}
原创粉丝点击