您的位置:首页 > 其它

【贪心】NOIP2011day2观光公交

2015-08-08 12:00 155 查看
题目描述:风景迷人的小城 Y 市,拥有n 个美丽的景点。由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务。观光公交车在第0 分钟出现在1号景点,随后依次前往2、3、4……n 号景点。从第i 号景点开到第i+1 号景点需要Di分钟。任意时刻,公交车只能往前开,或在景点处等待。

设共有 m 个游客,每位游客需要乘车1 次从一个景点到达另一个景点,第i 位游客在Ti 分钟来到景点Ai,希望乘车前往景点Bi(Bi>Ai)(Bi>Ai)。为了使所有乘客都能顺利到达目的地,公交车在每站都必须等待需要从该景点出发的所有乘客都上车后才能出发开往下一景点。假设乘客上下车不需要时间。

一个乘客的旅行时间,等于他到达目的地的时刻减去他来到出发地的时刻。因为只有一辆观光车,有时候还要停下来等其他乘客,乘客们纷纷抱怨旅行时间太长了。于是聪明的司机ZZ 给公交车安装了k 个氮气加速器,每使用一个加速器,可以使其中一个Di减1。对于同一个Di可以重复使用加速器,但是必须保证使用后Di大于等于0。求所有乘客的旅行时间总和的最小值。

我一开始以为DP,因为加速器的选择会对后面如何选择加速器产生影响。就只得了30分 /(ㄒoㄒ)/~~

然而这是一个贪心…知道真相的我眼泪掉下来 /(ㄒoㄒ)/~~

其实只要不往DP方向去想,很容易想到贪心。

#include <iostream>
#include <cstdio>
#define MAXN 1050
#define MAXM 10050
using namespace std;

int n ,m ,k ,ans ;
int d[MAXN] ,off[MAXN] ,lea[MAXN] ,arr_t[MAXN] ,g[MAXN] ;
int t[MAXM] ,a[MAXM] ,b[MAXM] ;

int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<n;++i)
scanf("%d",&d[i]);
for(int i=0;i<m;++i)
{
scanf("%d%d%d",&t[i],&a[i],&b[i] );
++off[b[i]] ;
lea[a[i]]=max(lea[a[i]],t[i]);
}
for(int i=1;i<=n;++i)
off[i]+=off[i-1];
for(int i=2;i<=n;++i)
arr_t[i]=max(arr_t[i-1],lea[i-1])+d[i-1];
for(int i=0;i<m;++i)
ans+=arr_t[b[i]]-t[i];
int maxn ,flag ;

while(k)
{
g
=g[n-1]=n;
for(int i=n-2;i>0;--i)
if(arr_t[i+1]<=lea[i+1])
g[i]=i+1;
else g[i]=g[i+1];
maxn=flag=0 ;
for(int i=1;i<=n;++i)
if(off[g[i]]-off[i]>maxn&&d[i]>0)
maxn=off[g[i]]-off[i] ,flag=i ;
if(!maxn)break;
ans-=maxn;
--d[flag] ,--k ;
for(int i=2;i<n;++i)
arr_t[i]=max(arr_t[i-1],lea[i-1])+d[i-1];
}
printf("%d",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: