日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

分治优化决策单调性

發布時間:2025/3/19 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 分治优化决策单调性 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

<!--more-->

分治優化決策單調性

在我們了解的DP方程中,經常會有$f[i]=sum_{max}/sum_{min}/min/max{f[j]+calc(i,j)}$,并且calc(i,j)滿足四邊形不等式,這種方程存在,而通常情況下,calc(i,j)可以非常輕松的得出,比如說$x^q$,或者sum[i][j],又或者是什么其他的東西。但是,有些時候,我們并不能在$O(logn)/O(1)$的時間內得出,這種情況下,正常通過維護單調隊列并且二分的方法就沒辦法完成了。

這種情況下,我們就需要考慮calc(i,j)的求法了,這種時候,如果我們發現calc(i,j)可以通過分治來均攤$O(nlogn)$處理出來的時候,我們就可以通過整體二分來維護決策單調性來轉移,保證整體時間復雜度的正確性。

例題時間

BZOJ 5125: [Lydsy1712月賽]小Q的書架

這道題很顯然,我們要將序列分成$K$段使得這$K$段的逆序對和最小。

正常DP方程,f[i][j]=f[i-1][k]+calc(k+1,j);

我們發現calc(k+1,j)滿足$calc(i,j)+calc(i-1,j+1) \ge calc(i,j+1)+calc(i+1,j)$所以這個具有決策單調性,但是,我們雖然將DP方程的時間復雜度減少到$O(nklogn)$但是,我們發現,每次計算calc(i,j)還是$O(n)$的,所以總時間復雜度不變,因此,我們考慮用分治優化決策單調性。

我們考慮在整體二分的過程中,calc(i,j)每一層的時間復雜度為$O(n)$,而一共$logn$層,所以時間復雜度為$O(nlogn)$,這樣,在DP的同時,calc(i,j)的時間復雜度也降低了,而為了維護calc(i,j)需要用到樹狀數組求逆序對,所以總時間復雜度為$O(nklog^2n)$顯然,是可以做的...

如果K出的大一點的話,我覺得可以帶權二分...所以時間復雜度可以達到$O(nlogklog^2n)$,所以還可以加強加強,嗯,就是下一道考試題了!

附上代碼:

#include <cstdio> #include <algorithm> #include <cstring> #include <cstdlib> #include <iostream> #include <cmath> #include <queue> #include <bitset> using namespace std; #define N 40005 int f[N],sum[N],g[N],n,k,rl,rr,ret,a[N]; void fix(int x,int v){for(;x<N;x+=x&-x)sum[x]+=v;} int find(int x){int re=0;for(;x;x-=x&-x)re+=sum[x];return re;} void get(int l,int r) {while(rl<l)fix(a[rl],-1),ret-=find(a[rl++]-1);while(rl>l)fix(a[--rl],1),ret+=find(a[rl]-1);while(rr<r)fix(a[++rr],1),ret+=find(n)-find(a[rr]);while(rr>r)fix(a[rr],-1),ret-=find(n)-find(a[rr--]); } void solve(int l,int r,int L,int R) {if(l>r)return ;int m=(l+r)>>1,p;for(int i=min(m-1,R);i>=L;i--){get(i+1,m);if(g[i]+ret<f[m])f[m]=g[i]+ret,p=i;}solve(l,m-1,L,p);solve(m+1,r,p,R); } int main() {scanf("%d%d",&n,&k);rr=n,rl=1;for(int i=1;i<=n;i++)scanf("%d",&a[i]),f[i]=f[i-1]+find(n)-find(a[i]),fix(a[i],1);ret=f[n];for(int i=2;i<=k;i++){memcpy(g,f,sizeof(f[0])*(n+1));memset(f,0x3f,sizeof(f[0])*(n+1));solve(1,n,1,n);}printf("%d\n",f[n]); }

  

轉載于:https://www.cnblogs.com/Winniechen/p/9862745.html

總結

以上是生活随笔為你收集整理的分治优化决策单调性的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。