題目大意:
給出一個整數序列,可以花費1的代價把一個數+1或1,求把它變成不上升序列的最小代價。n<=500000;
解題思路:
令 爲前個數,調整出最大值不超過 的最小代價,那麼 是一條不升的折線
考慮轉移
這實際上是兩條折線合併一下 我們討論兩者的位置關係
先加一個下凸折線,再取個前綴min 。
取前綴min,就是把斜率>=1的部分刪掉,實現的話只需要在堆中記下所有的折點。
附一張題解的圖方便理解:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int getint()
{
int i=0,f=1;char c;
for(c=getchar();(c!='-')&&(c<'0'||c>'9');c=getchar());
if(c=='-')c=getchar(),f=-1;
for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
priority_queue<int>q;
int main()
{
//freopen("lx.in","r",stdin);
int n=getint(),x;ll ans=0;
for(int i=1;i<=n;i++)
{
x=-getint();q.push(x);
if(q.top()>x)ans+=q.top()-x,q.pop(),q.push(x);
}
cout<<ans<<'\n';
}