思路:这题很有意思,看了别人的思路发现用到了没用过的技巧,把区间拆成两个点起点和终点,然后按点从小到大排序,每次扫到的点如果是右端点则更新该区间价值的最小花费,即如果该区间的价值为value,则dp[value]=min(dp[value],cost),如果是左端点则用该区间的花费和前面已知的最小花费求出当前花费来更新答案。具体操作看代码:
#include<iostream>
#include<cmath>
#include<queue>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
#include<string>
#include<utility>
#include<map>
#include<stack>
#include<vector>
#define maxn 200005
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const double eps = 1e-8;
const int mod = 1e9 + 7;
struct node{
int index, mark, value, cost;
}p[maxn << 1];
bool cmp(node a, node b){
return a.index < b.index || (a.index == b.index&&a.mark < b.mark);
}
int dp[maxn];
int main(){
int n, x;
scanf("%d%d", &n, &x);
int number = 0;
while (n--){
int l, r, cost;
scanf("%d%d%d", &l, &r, &cost);
p[number].index = l;
p[number + 1].index = r;
p[number].mark = 0;
p[number + 1].mark = 1;
p[number].value = p[number + 1].value = r - l + 1;
p[number].cost = p[number + 1].cost = cost;
number += 2;
}
sort(p, p + number, cmp);
memset(dp, inf, sizeof(dp));
int ans = inf << 1;
for (int i = 0; i < number; i++){
if (p[i].mark)
dp[p[i].value] = min(dp[p[i].value], p[i].cost);
else{
int value = x - p[i].value;
if (value >= 0 && dp[value] != inf)
ans = min(ans, dp[value] + p[i].cost);
}
}
ans = ans == inf << 1 ? -1 : ans;
printf("%d\n", ans);
}