思路: 这种题蛮经典的,还是跟线段有关- -,以前做过类似的,还是没想出正解来, 二分xjb搞了一会- -, 他要求不相交, 而且相加等于x,其实很简单,把所有端点从小到大排序, 如果这个点是左端点, 那么他可以加上前面已经走过的完整的区间中的差等于 x - 当前区间差 中 cost最小的值, 怎样记录前面走完区间的cost呢。。 只要碰到右端点, 就把他这个区间的差更新最小的。。用一个sum数组记录,这样只要sum数组有值,说明前面完整的区间的差有值。。跟http://blog.csdn.net/qq_34374664/article/details/72377345这题有点像, 然后用了一个数组记录出现过得值得方法也挺经典。。这里有个小trick, 这里排序的时候,让左端点在前面, 因为不想交要求端点也不一样,端点值相等时,左端点在前面,不会把前面区间的右端点算进去。。因为这不是个完整的区间。。
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 5;
const int INF = 2e9 + 5;
struct node
{
int x, y,cost, type;
node(){}
node(int xx, int yy, int cc, int tt): x(xx), y(yy), cost(cc), type(tt){}
};
int cmp(node a, node b)
{
if(a.x == b.x)
return a.type < b.type;
return a.x < b.x;
}
vector<node> v;
int sum[maxn];
int main()
{
int n, x;
while(~scanf("%d%d", &n, &x))
{
int l, r, c;
v.clear();
memset(sum, 0, sizeof(sum));
for(int i = 1; i <= n; i++)
{
scanf("%d%d%d", &l, &r, &c);
v.push_back(node(l, r, c, -1));
v.push_back(node(r, l, c, 1));
}
sort(v.begin(), v.end(), cmp);
int ans = INF;
for(int i = 0; i < v.size(); i++)
{
if(v[i].type == -1)
{
int temp = v[i].y-v[i].x+1;
if(temp >= x || !sum[x-temp]) continue;
ans = min(ans, sum[x-temp]+v[i].cost);
}
else
{
int temp = v[i].x-v[i].y+1;
if(!sum[temp] || sum[temp] > v[i].cost)
sum[temp] = v[i].cost;
}
}
if(ans != INF)
printf("%d\n", ans);
else
printf("-1\n");
}
return 0;
}