Description
风景迷人的小城 Y 市,拥有
n
个美丽的景点。由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务。观光公交车在第0 分钟出现在1号景点,随后依次前往2、3、4……
Input
第1行是3个整数
n
,
第2行是
第3行至
m+2
行每行3个整数
Ti
,
Ai
,
Bi
,每两个整数之间用一个空格隔开。
第
i+2
行表示第i位乘客来到出发景点的时刻,出发的景点编号和到达的景点编号。
1≤n≤1,000
,
1≤m≤10,000
,
0≤k≤100,000
,
0≤Di≤100
,
0≤Ti≤100,000
。
Output
共一行,包含一个整数,表示最小的总旅行时间。
Sample Input
3 3 2
1 4
0 1 3
1 1 2
5 2 3
Sample Output
10
输入输出样例说明
对
D2
使用2 个加速器,从2 号景点到3 号景点时间变为2 分钟。
公交车在第 1 分钟从1 号景点出发,第2 分钟到达2 号景点,第5 分钟从2 号景点出发,第7 分钟到达3 号景点。
第 1 个旅客旅行时间
7−0=7
分钟。
第 2 个旅客旅行时间
2−1=1
分钟。
第 3 个旅客旅行时间
7−5=2
分钟。
总时间 7+1+2 = 10 分钟。
HINT
方法
贪心,具体见代码
代码
#include <cstdio>
#include <algorithm>
const int maxn=1000;
const int maxm=10000;
struct data
{
int start,end,time;
};
data a[maxm+10];
int n,m,k,ans;
int dist[maxn+10],last[maxn+10],g[maxn+10],sum[maxn+10],enter[maxn+10];
//dist[i]代表i到i+1的距离
//last[i]代表最后一个到达第i个站点的到达时间
//enter[i]代表公交到达i号站点的时间
//g[i]代表如果i到i+1设氮气加速器,那么最多能够使到几号站点的乘客所花费的时间更少
//sum[i]代表乘客中到达i站点的总人数
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1; i<n; i++)
{
scanf("%d",&dist[i]);
}
for(int i=1; i<=m; i++)
{
scanf("%d%d%d",&a[i].time,&a[i].start,&a[i].end);
last[a[i].start]=std::max(last[a[i].start],a[i].time);
sum[a[i].end]++;
//更新last[]数组和sum[]数组
}
for(int i=1; i<=n; i++)
{
sum[i]+=sum[i-1];
//更新sum[]数组
}
enter[1]=last[1];
for(int i=2; i<=n; i++)
{
enter[i]=std::max(enter[i-1],last[i-1])+dist[i-1];
//更新enter[]数组
}
for(int i=1; i<=m; i++)
{
ans+=enter[a[i].end]-a[i].time;
//如果不使用氮气加速器,那么得到的答案
}
while(k--)
{
g[n]=g[n-1]=n;
int maxx=0,f;
//maxx代表当次减速所能减掉的最大时间
//f代表当次减速应当减速的位置
for(int i=n-2; i>0; i--)
{
g[i]=(enter[i+1]<=last[i+1])?(i+1):g[i+1];
//更新g[i]
}
for(int i=1; i<n; i++)
{
if((sum[g[i]]-sum[i]>maxx)&&(dist[i]>0))
//如果当前位置更新的最大值大于以前位置的最大值
//那么更新这个值
{
maxx=sum[g[i]]-sum[i];
f=i;
}
}
ans-=maxx;
dist[f]--;
//更新dist[]数组和ans值
for(int i=2; i<=n; i++)
{
enter[i]=std::max(enter[i-1],last[i-1])+dist[i-1];
//更新enter[]数组
}
}
printf("%d\n",ans);
//输出答案
return 0;
}