您的位置:首页 > 其它

noip2011 观光公交 递推+贪心

2016-11-07 20:46 375 查看
考虑一个加速器对答案的影响,如果加速后一个人下车了,那么这个人时间缩短了一秒。所以在没有发生车等人的情况下,每当有一人下车,时间就会缩短一秒。然后各个加速器之间是互不影响的。所以可以贪心。

预处理出每个点可以向后拓展,直到发生车等人的长度。再用前缀和维护一段区间下车的人数。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 20005
using namespace std;
struct per
{
int start,T,to;
}a[maxn];
int n,m,K,ans;
int f[maxn],rec[maxn],g[maxn],dis[maxn],sum[maxn];
int main()
{
scanf("%d%d%d",&n,&m,&K);
for(int i=1;i<n;i++)
scanf("%d",&dis[i]);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a[i].T,&a[i].start,&a[i].to);
f[a[i].start]=max(f[a[i].start],a[i].T);
sum[a[i].to]++;
}
for(int i=2;i<=n;i++)
sum[i]+=sum[i-1];
rec[1]=0;
for(int i=2;i<=n;i++)
rec[i]=max(rec[i-1],f[i-1])+dis[i-1];
for(int i=1;i<=m;i++)
ans+=rec[a[i].to]-a[i].T;
while(K)
{
g
=n;
g[n-1]=n;
for(int i=n-2;i;i--)
{
if(rec[i+1]<=f[i+1])
g[i]=i+1;
else g[i]=g[i+1];
}
int Max=0,j;
for(int i=1;i<=n;i++)
if(sum[g[i]]-sum[i]>Max&&dis[i]>0)
Max=sum[g[i]]-sum[i],j=i;
if(!Max) break;
ans-=Max;
dis[j]--;
K--;
rec[1]=0;
for(int i=2;i<=n;i++)
rec[i]=max(rec[i-1],f[i-1])+dis[i-1];
}
cout<<ans;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  贪心 递推