题意
给出一些闭区间(始末+代价),选取两段不重合区间使长度之和恰为x且代价最低
思路
相同持续时间的放在一个vector中,内部再对起始时间排序,从后向前扫获取对应起始时间的最优代价,存在minn中,对时间 i 从前向后扫,在对应的k-i中二分找第一个不重合的区间,其对应的minn加上 i 的cost即为出发时间为 i 时的最优解
代码
#include<bits/stdc++.h>
using namespace std;
int n, k;
struct EVE{
int st,ed,val;
EVE(){
}
EVE(int a,int b, int c){
st = a, ed = b, val = c;
}
};
int f,t,c;
vector<EVE> v[];
vector<int> minn[];
int tmp[];
bool cmp(EVE a, EVE b){
return a.st<b.st;
}
int main(){
scanf("%d%d",&n,&k);
for(int i = ;i<n;i++){
scanf("%d%d%d",&f,&t,&c);
if(t-f+ >= k) continue;
v[t-f+].push_back({f,t,c});
}
for(int i = ;i<=k;i++) sort(v[i].begin(),v[i].end(),cmp);
for(int i = ;i<=k;i++){
for(int j = v[i].size()-;j>=;j--){
if(j==v[i].size()-) tmp[j]=v[i][j].val;
else tmp[j]=min(v[i][j].val,tmp[j+]);
}
for(int j = ;j<v[i].size();j++){
minn[i].push_back(tmp[j]);
}
}
long long ans = 1e12;
for(int i = ;i<=k;i++){
if(v[k-i].empty()) continue;
for(int j = ;j<v[i].size();j++){
int ed = v[i][j].ed;
long long cost = v[i][j].val;
int le = , ri = v[k-i].size()-;
if(v[k-i][ri].st<=ed) continue;
int mid = le+ri>>;
while(le<ri){
mid = le+ri>>;
if(v[k-i][mid].st<=ed) le = mid+;
else ri = mid;
}
ans = min(ans, cost+minn[k-i][le]);
}
}
if(ans == 1e12) printf("-1");
else printf("%I64d",ans);
return ;
}