1139 观光公交
2011年NOIP全国联赛提高组
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
查看运行结果
本题为NOIP2011提高组day2第三题,其实这道题虽然被放在第三题但它仅仅只需要一个贪心就好,我们首先记录下来到每一站下车的人数,然后枚举每一个加速器,由于每个乘客的旅行时间只与他到达的时间与下车的时间有关,因此,我们在枚举每一个加速器的时候,只需要把能够造福最多人的那一段路加速即可,于是我们可以记录每一段路所造福的人数,我们暂定每个景点的出发时间为需要从该景点上车的最晚到达的乘客,那么到达时间即为上一个景点的出发时间或到达时间更大的一个值加上从上一个景点到该景点所需要的时间。如果某个景点的出发时间小于到达时间,那么说明若在这段旅程中使用加速器,能够造福到下一个景点下车的人。通过这个,我们就可以贪心了,然后每次贪心完之后都更新到达景点的时间即可。为了方便计算,我在初始化的时候把所有人的到达景点的时间都减去,这样就不用最后再减了,就可以直接求需要在每个景点下车的人数*到达该景点的时间的和就行了。
AC代码:
#includeusing namespace std;#define N 11000int d[N],num[N],data[N],tim[N],last[N];int n,m,k,ans,max1,cct;int main(){ scanf("%d%d%d",&n,&m,&k); for(int i=2;i<=n;i++) scanf("%d",&d[i]); for(int i=1,a,b,c;i<=m;i++){ scanf("%d%d%d",&a,&b,&c); ans-=a; num[c]++; last[b]=max(last[b],a); } for(int i=2;i<=n;i++){ tim[i]=max(tim[i-1],last[i-1])+d[i]; } for(int i=1;i<=k;i++){ for(int j=n;j>=2;j--){ data[j]=num[j]; if(last[j] max1&&d[j]>0){ max1=data[j]; cct=j; } } d[cct]--; for(int j=cct;j<=n;j++){ tim[j]=max(tim[j-1],last[j-1])+d[j]; } } for(int i=2;i<=n;i++){ ans+=num[i]*tim[i]; } printf("%d\n",ans); return 0;}