[APIO / CTSC 2007] Data Backup

[APIO / CTSC 2007] Data Backup

The real problem greed is good

After some interval is taken, both ends of the range next to no longer take, but we can discard this period, to get the next two

This greedy strategy how to maintain it?

We stack maintenance greedy, after each selection of this interval, the interval on both sides into a single space, the weight is the \ (w_ {i-1} + w_ {i + 1} -w_i \)

This intermediate section is discarded, taking both sides of

But such an approach can only be done once discarded, in fact we may have many times, but we only use it to promote

With a doubly linked list maintenance, right after changing the value is \ (pre W_ {[I]} + {W_ NXT [I]} - W_i \) , which is equally applicable for a plurality of combinations of

Note that at this point whether the record has been merged out

#include<cstdio> 
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
 
#define reg register
typedef long long ll;
#define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
#define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)
  
char IO;
int rd(){
    int s=0,f=0;
    while(!isdigit(IO=getchar())) if(IO=='-') f=1;
    do s=(s<<1)+(s<<3)+(IO^'0');
    while(isdigit(IO=getchar()));
    return f?-s:s;
}
 
template <class T> inline void cmin(T &a,T b){ ((a>b)&&(a=b)); }
template <class T> inline void cmax(T &a,T b){ ((a<b)&&(a=b)); }
 
 
const int N=1e5+10,K=21,INF=1e9+10;
 
int n,k;
int d[N];
struct Node{
    int x,id;
    bool operator < (const Node __) const {
        return x>__.x;
    }
};
priority_queue <Node> Q;
int L[N],R[N];
int ans;
int del[N];
 
void Del(int x) {
    L[R[x]]=L[x];
    R[L[x]]=R[x];
    del[x]=1;
}
 
int main(){
    n=rd(),k=rd();
    rep(i,1,n) d[i]=rd(),L[i]=i-1,R[i]=i+1;
    R[n+1]=n,R[0]=1;
    drep(i,n,2) {
        d[i]-=d[i-1];
        Q.push((Node){d[i],i});
    }
    d[1]=d[n+1]=INF;
    rep(i,1,k) {
        int t=Q.top().id; Q.pop();
        if(del[t]) {
            i--;
            continue;
        }
        ans+=d[t];
        d[t]=d[L[t]]+d[R[t]]-d[t];
        Del(L[t]),Del(R[t]);
        Q.push((Node){d[t],t});
    }
    printf("%d\n",ans);
}
 

Guess you like

Origin www.cnblogs.com/chasedeath/p/11821910.html