标签:中间 HERE 直接 output reac flag ios ESS job
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 4422 | Accepted: 1482 |
Description
Input
Output
Sample Input
3 0 4 0 2 3 3 4 2 0 0 1
Sample Output
5
Hint
Source
题意:
一个[L, R]的区间,有n头牛,每头牛可以清理一个固定区间,需要花费一定的价格。现在要清理[L,R]这个区间,需要花费最少的价格是多少。
思路:
用f[x]表示清理区间[L, x]需要花费的最小价格。
对于一头牛,他可以清理的区间是[a,b],那么因为中间不能间断,所以f[b] = min(f[x]) + c其中x是属于[a-1,b]区间的。
每次状态转移都要取一个区间最小值,并且更新一个点的值,所以用上线段树来维护。
首先将所有的牛按照结束的区间进行排序,然后DP。
因为时间是从0开始,所以我给所有的时间都加了2,这样a-1就还是从1开始。
要注意的是update()时,并不是直接将值改为val,而是取较小值,这里WA了一会。
1 #include <iostream> 2 #include <set> 3 #include <cmath> 4 #include <stdio.h> 5 #include <cstring> 6 #include <algorithm> 7 using namespace std; 8 typedef long long LL; 9 #define inf 0x7f7f7f7f 10 11 const int maxn = 1e5 + 5; 12 const int maxtime = 86500; 13 struct node{ 14 int st, ed, cost; 15 }cow[maxn]; 16 bool cmp(node a, node b) 17 { 18 return a.ed < b.ed; 19 } 20 LL tree[maxn << 2];//区间中f[]最小值 21 int n, L, R; 22 23 void pushup(int rt) 24 { 25 tree[rt] = min(tree[rt << 1], tree[rt << 1|1]); 26 } 27 28 void build(int rt, int l, int r) 29 { 30 if(l == r){ 31 tree[maxn] = inf; 32 return; 33 } 34 int mid = (l + r) / 2; 35 build(rt<<1, l, mid); 36 build(rt<<1|1, mid + 1, r); 37 pushup(rt); 38 } 39 40 void update(int x, LL val, int l, int r, int rt) 41 { 42 if(l == r){ 43 tree[rt] = min(tree[rt], val); 44 return; 45 } 46 int m = (l + r) / 2; 47 if(x <= m){ 48 update(x, val, l, m, rt<<1); 49 } 50 else{ 51 update(x, val, m + 1, r, rt<<1|1); 52 } 53 pushup(rt); 54 } 55 56 LL query(int L, int R, int l, int r, int rt) 57 { 58 if(L <= l && R >= r){ 59 return tree[rt]; 60 } 61 int m = (l + r) / 2; 62 LL ans = inf; 63 if(L <= m){ 64 ans = min(ans, query(L, R, l, m, rt<< 1)); 65 } 66 if(R > m){ 67 ans = min(ans, query(L, R, m + 1, r, rt<<1|1)); 68 } 69 pushup(rt); 70 return ans; 71 } 72 73 int main() 74 { 75 while(scanf("%d%d%d", &n, &L, &R) != EOF){ 76 L+=2;R+=2; 77 memset(tree, 0x7f, sizeof(tree)); 78 for(int i = 1; i <= n; i++){ 79 scanf("%d%d%d", &cow[i].st, &cow[i].ed, &cow[i].cost); 80 cow[i].st+=2;cow[i].ed+=2; 81 } 82 sort(cow + 1, cow + 1 + n, cmp); 83 84 build(1, 1, R); 85 86 update(L - 1, 0, 1, R, 1); 87 //cout<<"yes"<<endl; 88 int far = L; 89 bool flag = true; 90 for(int i = 1; i <= n; i++){ 91 if(cow[i].st > far + 1){ 92 flag = false; 93 // break; 94 } 95 int a = max(L - 1, cow[i].st - 1); 96 int b = min(R, cow[i].ed); 97 //cout<<a<<" "<<b<<endl; 98 LL f = query(a, b, 1, R, 1); 99 f += cow[i].cost; 100 //cout<<f<<endl; 101 update(b, f, 1, R, 1); 102 far = max(far, cow[i].ed); 103 //cout<<far<<endl; 104 } 105 //cout<<"yes"<<endl; 106 107 LL ans = query(R, R, 1, R, 1); 108 if(ans >= inf){ 109 printf("-1\n"); 110 } 111 else{ 112 printf("%lld\n", ans); 113 114 //else{ 115 // printf("-1\n"); 116 } 117 118 } 119 120 }
poj3171 Cleaning Shifts【线段树(单点修改区间查询)】【DP】
标签:中间 HERE 直接 output reac flag ios ESS job
原文地址:https://www.cnblogs.com/wyboooo/p/9808378.html