题解 P4712 【「生物」能量流动】
感觉纯贪心的一道题,加上一点优化,就差不多了,我是比赛时打了个8ms的程序,感觉还是好慢。
因为你作为顶级的掠食者,要想获得最大的能量,那么肯定对于每种生物都是要刚好满足它的需求。
由题意可知,要使所获得的最大就要让损失的最少。那么贪心策略便就出来了。便是每种生物尽量从最小等级的生物获得能量。 然后优化就是:较小等级的生物可能能量已经分配到0。那么就用一个vis数来表示已经为零的低等级的生物标号。(初始为0)
#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define In inline
#define R register
#define N 100005
using namespace std;
int n,vis;
int a,r;
double d[100005],k,sum;//double注意啊!
int read()
{
int x=0;char ch=getchar();
while(ch>'9'||ch<'0')ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();//位运算快读
return x;
}
int main()
{
n=read();a=read();d[0]=a;
for(R int i=1;i<=n;++i)
{
k=read(),d[i]=k,r=read();
for(int j=vis/*vis记录最小*/;j<=r;++j)
{
if(!d[j]) vis=j;
if(d[j]*0.2>=k) {d[j]=(d[j]-(k*5));k=0;break;}
else k=(k-d[j]*0.2),d[j]=0;
}
if(k>0) {cout<<"-1"<<endl;return 0;}
//若还大于0,无法满足,输出-1。
}
for(int i=vis;i<=n;++i) sum+=d[i]*0.2;//加能量和。
printf("%lf\n",sum);
return 0;
}