jzoj3859-孤独一生【dp,树状数组】
生活随笔
收集整理的這篇文章主要介紹了
jzoj3859-孤独一生【dp,树状数组】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目鏈接:https://jzoj.net/senior/#main/show/3859
題目大意
nnn個臺階,第iii個高度為hih_ihi?,把它分為兩個集合,使得兩個集合中相鄰的hih_ihi?差值和最小。
解題思路
設fif_ifi?表示剛好處理到iii且目前集合開頭是iii的最小差值
定義si=∑j=1i∣hj?hj?1∣s_i=\sum_{j=1}^i|h_j-h_{j-1}|si?=j=1∑i?∣hj??hj?1?∣
然后有轉移方程fi=min{fj+si?1?sj+∣hi?hj?1∣}(j∈[1..i?1])f_{i}=min\{f_j+s_{i-1}-s_j+|h_i-h_{j-1}|\}(j\in[1..i-1])fi?=min{fj?+si?1??sj?+∣hi??hj?1?∣}(j∈[1..i?1])
考慮用數據結構優化上面的dpdpdp,我們將情況分為:
用兩個樹狀數組分開維護后面的minminmin值即可。
時間復雜度O(nlog?n)O(n\log n)O(nlogn)
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long #define lowbit(x) (x&-x) using namespace std; const ll N=5e5+10; ll n,m,h[N],b[N],s[N],f[N],ans; struct Tree_Array{ll t[N];void Change(ll x,ll val){while(x<=m){t[x]=min(t[x],val);x+=lowbit(x);}}ll Ask(ll x){ll ans=2147483647;while(x){ans=min(ans,t[x]);x-=lowbit(x);}return ans;} }Ta,Tp; int main() {//freopen("data.txt","r",stdin);memset(Ta.t,0x3f,sizeof(Ta.t));memset(Tp.t,0x3f,sizeof(Tp.t));scanf("%lld",&n);for(ll i=1;i<=n;i++){scanf("%lld",&h[i]);b[i]=h[i];s[i]=s[i-1]+abs(h[i]-h[i-1]);}b[n+1]=0;sort(b+1,b+2+n);m=unique(b+1,b+2+n)-b-1;ans=1e18;ll lp=1,la=m;for(ll i=1;i<=n;i++){ll pre=lower_bound(b+1,b+1+m,h[i])-b;ll aft=m-pre+1;f[i]=min(s[i-1]+h[i]+Tp.Ask(pre),s[i-1]-h[i]+Ta.Ask(aft));if(i==1) f[i]=h[i];Tp.Change(lp,f[i]-s[i]-h[i-1]);Ta.Change(la,f[i]-s[i]+h[i-1]);ans=min(ans,f[i]+s[n]-s[i]);la=aft;lp=pre;}printf("%lld",ans); }總結
以上是生活随笔為你收集整理的jzoj3859-孤独一生【dp,树状数组】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《暗黑破坏神 4:憎恨之躯》游戏资料片明
- 下一篇: 报告称2023Q3全球PC CPU出货量