Luogu P3620 [APIO / CTSC 2007]データのバックアップ

トピック
わずかに後方へ凸最適化の選手。
明らかに、我々は選択した\(K \)隣接のペアを、私たちは、選挙後にタイトルの差動意味に変換することができます\(K \)非隣接数と最小を作ります。
私たちは、貪欲を考える:すべての選挙は最小限。エラーの貪欲な性質は明らかです。
我々は戻ってするメカニズムを追加しました:
数の除去\(\)その後、我々はその横に2つの数値を入れて\(B、C \)取り外し、この位置に新しい番号を入れて\(B + CA \)
その後、我々は次のリストの維持に最小数を維持するために、スタックを使用して、場所内のレコードの数を削除するならば、バレルを開きます。
それのこの貪欲な正しさを理解する方法:あなたが現在の最小点を選択しない場合は、横に2点を選択するようにしています。
ただ、自分が理解することができますについて考えます。

#include<bits/stdc++.h>
using namespace std;
const int N=100007,inf=0x3f3f3f3f;
struct node{int v,p;}t;
int operator<(node a,node b){return a.v>b.v;}
int f[N],l[N],r[N],v[N];
priority_queue<node>q;
void del(int x){l[x]=l[l[x]],r[x]=r[r[x]],r[l[x]]=x,l[r[x]]=x;}
int read(){int x;scanf("%d",&x);return x;}
int main()
{
    int n=read(),m=read(),i,ans=0,p;
    for(i=0;i<n;++i) v[i]=read();
    for(i=n-1;i;--i) v[i]-=v[i-1],l[i]=i-1,r[i]=i+1,q.push((node){v[i],i});
    v[0]=v[n]=inf;
    for(i=1;i<=m;++i)
    {
    while(f[q.top().p]) q.pop();
    t=q.top(),q.pop(),p=t.p,ans+=t.v,f[l[p]]=f[r[p]]=1,v[p]=v[l[p]]+v[r[p]]-v[p],q.push((node){v[p],p}),del(p);
    }
    return !printf("%d",ans);
}

おすすめ

転載: www.cnblogs.com/cjoierShiina-Mashiro/p/11580347.html