题意:
给你\(n\)条线段以及每条线段的价格,每次给出一条线段后,你要买给出的所有线段,每次买的时候之前买的都会清空。每当你买两条不连续的线段时,中间的线段会赠送给你,让你求:每次给出你一条线段后,购买的所有线段需要的最小的价格。
思路:
答案只会有两种情况:1.买一条所有线段中最大的点所在线段和一条所有线段中最小的点所在线段。2.购买一条长线段,其余出现过的线段都包含在其中。答案就是这两种情况的最小值。求这两种情况的花费只需要简单贪心加上维护最大最小值即可。
代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <vector>
#include <cmath>
#include <queue>
#include <deque>
#include <set>
#include <map>
#define LL long long
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
#define pb push_back
using namespace std;
const int INF = 2e9;
int minn = INF, maxn = -1, chang;
LL minl = INF, minr = INF, changw = INF;
void solve()
{
minn = INF, maxn = -1, chang = 0, minl = INF, minr = INF, changw = INF;
int n;
scanf("%d",&n);
for(int i = 1; i <= n; i ++ )
{
int l, r;
LL w;
scanf("%d %d %lld",&l, &r, &w);
if(l <= minn)
{
if(l == minn) minl = min(w, minl);
else
{
minn = l;
minl = w;
}
}
if(r >= maxn)
{
if(r == maxn) minr = min(w, minr);
else
{
maxn = r;
minr = w;
}
}
if(r - l + 1 >= chang){
if(r - l + 1 == chang) changw = min(changw, w);
else
{
chang = r - l + 1;
changw = w;
}
}
if(maxn - minn + 1 == chang)
printf("%lld\n", min(changw, minl + minr));
else printf("%lld\n", minl + minr);
}
}
int main()
{
int test;
scanf("%d",&test);
while(test -- )
{
solve();
}
return 0;
}