专栏文章

P1315 [NOIP 2011 提高组] 观光公交 completed!

个人记录参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miq8nkmc
此快照首次捕获于
2025/12/04 00:45
3 个月前
此快照最后确认于
2025/12/04 00:45
3 个月前
查看原文
费劲千辛万苦终于过了!!!
正解还是很好想的,每次选会对总时间影响最大的边去加速就好了。
然后是每条边加速后的影响,从这个角度去想,想清楚了这道题就差不多拿下了。
问题在于我想到正解后,代码好久都没写出来,卡在了下面注释的地方QAQ。
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m,k,d[N];
struct people{
	int time,t;
}p[N];
int down[N],arrive[N],late[N];
int main(){
	cin>>n>>m>>k;
	for(int i=1;i<n;i++) cin>>d[i];
	int t;
	for(int i=1;i<=m;i++){
		cin>>p[i].time>>t>>p[i].t;
		down[p[i].t]++;
		late[t]=max(late[t],p[i].time);
	}
	int time=0;
	for(int i=1;i<=n;i++){
		arrive[i]=time;
		time=max(time,late[i]);
		time+=d[i];	
	}
	int max_time,aim,js;
	while(k--){
		max_time=0;
		for(int i=2;i<=n;i++){
			if(!d[i-1]) continue;
			js=0;
			for(int j=i;j<=n;j++){
				js+=down[j];
				if(arrive[j]<=late[j]) break;
			}
			if(js>max_time){
				max_time=js;
				aim=i;
			}
		}
		d[aim-1]--;
		for(int i=aim;i<=n;i++){
			arrive[i]--;
			if(arrive[i]<late[i]) break;		//此处是已经加速后的,如果加速后相等的话那离开时间也是比一开始早了一秒 
//			if(arrive[i]<=late[i]){
//				arrive[i]--;
//				break;
//			}
//			arrive[i]--;
		}
	}
	int ans=0;
	for(int i=1;i<=m;i++){
		ans+=arrive[p[i].t]-p[i].time;
	}
	cout<<ans<<endl;
	
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...