# A题
服务器维护
TimeLimit:1500MS MemoryLimit:128MB
64-bit integer IO format:%lld
Problem Description
Dsc最大的梦想就是有一款属于自己的游戏(不可能的),可以把自己的奇思妙想在虚拟的世界中创造出来,假设Dsc成功了,创造出了一款网游(小作坊的那种),现在为了节省成本,Dsc决定自己维护服务器健康,但总会有没时间的时候。
假设从S分钟开始,E分钟结束[S,E]这段时间Dsc是没有时间的,这时候Dsc需要找人来维护服务器,当然是有偿的。在[S,E]这段时间中有n个人有空余时间(不一定是全部[S,E])第i个人在ai,bi这段时间有空,共需要ci的管理费。
现在请帮Dsc算一算,在他没空的时间内[S,E],每天都至少有一个人在管理服务器所需要的最少花费是多少,如果没有任何方案使[S,E]时间内每天都至少有一个人在管理服务器则输出-1;
Input
第一行为三个整数n,S,E分别表示有n个人有空,在[S,E]时间内Dsc没空
接下来有n行,每行3个整数ai,bi,ci分别表示第i个人在[ai,bi]时间内有空,雇佣共需要ci管理费
1<=n<=1e5
0<=S<=E<=1e5
S<=ai<=bi<=E
1<=ci<=1e5
Output
Dsc在没空的时间找人管理服务器所需的最少花费,没有方案则输出-1
SampleInput
3 2 4
2 3 2
4 4 1
2 4 4
SampleOutput
3
---
[思路1]:
其实这个题目就是一个DP加上线段树维护即可AC, 根据题意容易得知,需要区间全覆盖,那么我们可以考虑先按L从小到大排序维护从[S, R]所花费的最小价值,可得状态为dp[i]代表从[s, i]区间覆盖的最小价值。
可得状态转移方程为
dp[i] = min(dp[i], quert_min(l - 1, i - 1)) + w)
即可AC
附上代码
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 15;
const LL inf = __LONG_LONG_MAX__;
int n, s, e;
struct Segtree{
LL arr[MAXN];
struct NODE{
int l, r;
LL mins;
}tree[MAXN << 2];
void build(int root, int l, int r){
tree[root].l = l, tree[root].r = r;
if(l == r){
tree[root].mins = arr[l];
return ;
}
int mid = (l + r) >> 1;
build(root << 1, l, mid);
build(root << 1 | 1, mid + 1, r);
tree[root].mins = min(tree[root << 1].mins, tree[root << 1 | 1].mins);
return ;
}
void update(int root, int num, LL val){
if(tree[root].l == num && tree[root].r == num){
tree[root].mins = val;
return ;
}
int mid = (tree[root].l + tree[root].r) >> 1;
if(num <= mid){
update(root << 1, num, val);
}
else{
update(root << 1 | 1, num, val);
}
tree[root].mins = min(tree[root << 1].mins, tree[root << 1 | 1].mins);
return ;
}
LL query(int root, int l, int r){
if(tree[root].l >= l && tree[root].r <= r){
return tree[root].mins;
}
int mid = (tree[root].l + tree[root].r) >> 1;
if(r <= mid){
return query(root << 1, l, r);
}
else if(l > mid){
return query(root << 1 | 1, l, r);
}
else{
return min(query(root << 1, l, mid), query(root << 1 | 1, mid + 1, r));
}
}
}seg;
struct Person{
int l, r;
LL value;
friend bool operator< (const Person &a, const Person &b){
if(a.l == b.l){
return a.value < b.value;
}
else{
return a.l < b.l;
}
}
}arr[MAXN];
LL dp[MAXN];
int main(){
ios::sync_with_stdio(false);
cin >> n >> s >> e;
s += 2, e += 2;
for(int i = 0; i < n; i ++){
cin >> arr[i].l >> arr[i].r >> arr[i].value;
arr[i].l += 2, arr[i].r += 2;
}
for(int i = s; i <= e; i ++){
seg.arr[i] = inf;
dp[i] = inf;
}
for(int i = 0; i < s; i ++){
seg.arr[i] = 0;
dp[i] = 0;
}
seg.build(1, 1, e);
sort(arr, arr + n);
for(int i = 0; i < n; i ++){
if(seg.query(1, arr[i].l - 1, arr[i].r - 1) != inf){
dp[arr[i].r] = min(dp[arr[i].r], seg.query(1, arr[i].l - 1, arr[i].r - 1) + arr[i].value);
seg.update(1, arr[i].r, dp[arr[i].r]);
}
}
if(dp[e] == inf){
cout << "-1\n";
}
else{
cout << dp[e] << endl;
}
return 0;
}
[思路2]:
对于整个数据进行建图,将区间能互相覆盖的点连接起来,然后跑最短路径
附上代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include