求调悬关
查看原帖
求调悬关
929151
xxr___楼主2024/7/10 12:46

我的思路是用 fi,0f_{i,0} 表示排序后,到第 i 个隔板左侧的最近距离, fi,1f_{i,1} 表示到第 i 个隔板右侧的最近距离。如果 i==ti==t 就特判。 最后最小距离加总的高度即为答案。 代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+5;
int f[N][3];
struct node{
	int l,r,h,id;
}t[N]; 
bool operator<(const node&a,const node&b){
	if(a.h==b.h) return a.l<b.l; 
	return a.h>b.h;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int n,s,to,S,T;
	cin>>n>>s>>to;
	for(int i=1;i<=n;++i){
		cin>>t[i].l>>t[i].r>>t[i].h;
		t[i].id=i;
	}
	sort(t+1,t+n+1);
	for(int i=1;i<=n;++i){
		if(t[i].id==s){
			S=i;
		}
		if(t[i].id==to){
			T=i;
		}
	}
	if(S>T){
		cout<<"-1";
		return 0;
	}
	for(int i=1;i<=n;++i) f[i][0]=f[i][1]=0x3f3f3f;
	f[S][0]=0;
	f[S][1]=t[S].r-t[S].l;
	int mn=0x3f3f3f;
//	cout<<S<<' '<<T<<endl;
	for(int i=S;i<=T;++i){
		for(int j=S+1;j<=T;++j){
			if(t[i].l>t[j].l&&t[j].r>=t[i].l){
				f[j][0]=min(f[j][0],f[i][0]+t[i].l-t[j].l);
				f[j][1]=min(f[j][1],f[i][0]+t[j].r-t[i].l);
				if(j==T){
					mn=min(mn,f[i][0]);
				}
			}
			if(t[i].r<t[j].r&&t[j].l<=t[i].r){
				f[j][0]=min(f[j][0],f[i][1]+t[i].r-t[j].l);
				f[j][1]=min(f[j][1],f[i][1]+t[j].r-t[i].r);
				if(j==T){
					mn=min(mn,f[i][1]);
				} 
			}
		}
	}
//	for(int i=1;i<=n;++i){
//		cout<<f[i][0]<<' '<<f[i][1]<<endl;
//	}
	cout<<mn+t[S].h-t[T].h;
	return 0;
}
//tomxi
2024/7/10 12:46
加载中...