1150: [CTSC2007]数据备份Backup
Posted mjtcn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1150: [CTSC2007]数据备份Backup相关的知识,希望对你有一定的参考价值。
1150: [CTSC2007]数据备份Backup
https://lydsy.com/JudgeOnline/problem.php?id=1150
分析:
堆+贪心。
每次选最小的并一定是最优的,如果不选这个最小的,那一定是为了取它左右两边(两条都要取才可能比当前优)。
如果先选了最小的,考虑后面如何撤销。选了这个后,左右两边的线段就要删了,那么在加入一个长度为:左边的长度+右边的长度-当前的线段的长度 的一条线段。
代码:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<iostream> 5 #include<cmath> 6 #include<cctype> 7 #include<set> 8 #include<queue> 9 #include<vector> 10 #include<map> 11 using namespace std; 12 typedef long long LL; 13 14 inline int read() { 15 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch==‘-‘)f=-1; 16 for(;isdigit(ch);ch=getchar())x=x*10+ch-‘0‘;return x*f; 17 } 18 19 const int N = 100005; 20 const int INF = 1e9; 21 22 int pre[N], nxt[N], d[N], a[N]; 23 bool vis[N]; 24 25 struct Edge{ 26 int len, id; 27 Edge() { } 28 Edge(int a, int b) { len = a, id = b; } 29 bool operator < (const Edge &A) const { 30 return len > A.len; 31 } 32 }; 33 priority_queue<Edge> q; 34 35 void del(int i) { 36 vis[i] = 1; 37 nxt[pre[i]] = nxt[i]; 38 pre[nxt[i]] = pre[i]; 39 } 40 41 int main() { 42 int n = read(), m = read(); 43 for (int i = 1; i <= n; ++i) d[i] = read(); 44 for (int i = 1; i < n; ++i) { 45 a[i] = d[i + 1] - d[i]; 46 q.push(Edge(a[i], i)); 47 } 48 a[0] = a[n] = INF; 49 for (int i = 1; i <= n; ++i) pre[i] = i - 1, nxt[i] = i + 1; 50 int ans = 0; 51 while (m --) { 52 while (vis[q.top().id]) q.pop(); 53 Edge now = q.top(); q.pop(); 54 ans += now.len; 55 int i = now.id, t; 56 t = min(a[pre[i]] + a[nxt[i]] - now.len, INF); 57 del(pre[i]); del(nxt[i]); 58 a[i] = t; q.push(Edge(a[i], i)); 59 } 60 cout << ans; 61 return 0; 62 }
以上是关于1150: [CTSC2007]数据备份Backup的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 1150: [CTSC2007]数据备份Backup
BZOJ-1150: [CTSC2007]数据备份Backup (贪心绝世好题)