题目连接

https://codeforces.com/contest/822/problem/C

解题思路

存两个数组中,一个按左端点从小到大排序,一个按右端点从小到大排序,遍历每一个,找到其对应的满足l<r的全部区间,保存区间长度对应的最小花费,对于遍历到的每一段区间,我们找到满足与其之和为x的另一段区间,维护最小花费即可。
这样可以保证,每一段区间的花费被存在了cost[区间长度]中,同时每次去维护答案的所有cost是满足区间不相交的最小花费。(需要自己理解一下)

AC代码

#include<bits/stdc++.h>
#define INF 2147483647
#define ll long long
using namespace std;
const int N=2e5+10;
ll ans=INF;
ll cost[N];
int n,x;
struct node
{
    int l,r;
    ll cost;    
}a[N],b[N];
bool cmp1(node aa,node bb)
{
    return aa.l<bb.l;
}
bool cmp2(node aa,node bb)
{
    return aa.r<bb.r;
}
int main()
{
    cin>>n>>x;
    for(int i=1;i<=n;i++) cin>>a[i].l>>a[i].r>>a[i].cost,b[i]=a[i];
    sort(a+1,a+n+1,cmp1);
    sort(b+1,b+n+1,cmp2);
    for(int i=1;i<N;i++) cost[i]=INF;
    for(int i=1,j=1;i<=n;i++)
    {
        while(j<=n && b[j].r<a[i].l)
        {
            cost[b[j].r-b[j].l+1]=min(cost[b[j].r-b[j].l+1],b[j].cost);
            j++;
        }
        int t=x-(a[i].r-a[i].l+1);
        if(t>0) ans=min(ans,cost[t]+a[i].cost);
    }
    if(ans==INF) puts("-1");
    else cout<<ans<<endl;
    return 0;
}

总结

大佬牛B