決策單調性優化入門

2022-09-12 05:36:12 字數 4039 閱讀 7323

對於乙個二元函式 \(w(l,r)\),如果有下面的命題成立,則稱 \(w\) 滿足四邊形不等式:

\[\forall a \leq b < c \leq d,~

w(a,c)+w(b,d) \leq w(a,d) + w(b,c)

\]如果二元函式 \(w(a,b)\) 滿足 \(w(a+1,b+1)+w(a,b) \leq w(a,b+1)+w(a+1,b)\) ,那麼 \(w(a,b)\) 滿足四邊形不等式。

證明

將兩式相加,然後化簡:

\[\begin

w(a,b)+w(a+1,b+1)+w(a+1,b)+w(a+2,b+1)&\leq w(a,b+1)+w(a+1,b)+w(a+1,b+1)+w(a+2,b)\\

w(a,b)+w(a+2,b+1)&\leq w(a,b+1)+w(a+2,b)

\end

\]以此類推,可以得到:

\[\forall a \leq b < c, w(a,c)+w(b,c+1) \leq w(a,c+1)+w(b,c)

\]可以對第二個數做類似的操作,可以得到:

\[\forall a \leq b < c \leq d,~

w(a,c)+w(b,d) \leq w(a,d) + w(b,c)

\]\(\rm q.e.d\)

考慮乙個形如下面式子的 \(\rm dp\) 轉移:

\[f(i)=\min_ \

\]設 \(p(i)\) 表示 \(f(i)\) 的最優決策點,即:

\[p(i)=\arg\min_ \

\]而這個 \(\rm dp\) 有決策單調性,當且僅當 \(p(i)\) 單調不降。

轉移引數 \(w(j,i)\) 滿足四邊形不等式 \(\rightarrow\)

\(f(i)\) 滿足決策單調性。

證明

\(\forall a < b < i < j\), 設 \(p(i) = b\),則有 \(f(b)+w(b,i)\leq f(a)+w(a,i)\)

根據四邊形不等式,有

\[w(a,i)+w(b,j) \leq w(a,j)+w(b,i)

\]將兩條式子相加,然後化簡,得到:

\[f(b)+w(b,j)\leq f(a)+w(a,j)

\]由此可以看出,對於 \(i\) 之後的所有狀態,其最優決策點都可以不是 \(a\) ,因此可以有 \(p(j)\ge b\) ,因此滿足決策單調性。

\(q\):上面的內容似乎只針對 \(\min\) ,那麼對於 \(\max\) 應該怎麼辦呢?

\(a\):把四邊形不等式的不等號取反即可。

決策單調性和斜率優化關聯性挺大的,但是本 \(\rm juruo\) 覺得兩個東西本質上有點不同。

\(\rightarrow\) 原題鏈結

可以得到轉移:

\[f(i)=\min_ \left\

\]其中 \(s_i = s_+|\mathrm_i|\)

設 \(w(i,j) = \left|s_i-s_j+(i-j-1)-l\right|^p\),顯然當前就是要證明這個東西滿足四邊形不等式。

根據四邊形不等式的性質,可以轉化為證明

\[w(i+1,j+1)+w(i,j) \leq w(i,j+1)+w(i+1,j)

\]這個證明不太顯然,需要稍微搞一搞。教給各位 \(\rm dalao\) 了。這裡主要介紹知道決策單調性之後的做法。

顯然,對於每個決策點 \(x\),都有乙個貢獻區間 \([l_x, r_x] (\forall k \in [l_x, r_x], p(k)=x)\) ,可以用二分求出對於決策點 \(x\),第乙個比決策點 \(y\) 優的位置,這個明顯可以使用二分求出,設其為 \(g(x,y)\)。

接著用單調佇列維護出 \(l\) 單調遞增的決策點序列。

顯然,對於佇列中相鄰的兩個決策 \(x,y~(x,顯然是 \(r_x = g(y,x)-1\)。

為了優化常數,可以在佇列中記錄 \(r_x\) 。

#include using namespace std;

typedef long double ll;

const int maxn = 1e5 + 5;

const ll inf = 1e18;

int n, p, q[maxn], ql, qr;

ll l, s[maxn], fr[maxn], f[maxn];

string str[maxn];

ll qpow(ll a, int b)

return ret;

}inline ll calc(int x, int y)

int bsearch(int x, int y)

return ans;

}void print_plan(int x)

void solve()

if (f[n] > inf)

printf("%.0lf\n", f[n]), print_plan(n);

printf("--------------------\n");

}int main()

\(\rightarrow\) 原題鏈結

和上一題的轉移方程非常類似,只不過 \(w(i,j)\) 的計算方法不同,需要使用資料結構優化,就不講了。

\(\rightarrow\)

\(\rm luogu\) 鏈結

題意非常清楚明白,可以直接設出 \(f(i,j)\) 表示將前 \(j\) 個元素分成 \(i\) 段的最小權值,可以得到轉移:

\[f(i,j) = \min_ \

\]其中 \(w(i,j)\) 表示區間 \([l,r]\) 中重複元素的對數,可以看出這個函式滿足四邊形不等式,但是這個函式的求值時間複雜度是 \(o(n)\) 的,因此不能使用先前的單調佇列優化了。這裡提出另一種優化決策單調性的方法:分治

這種方法適用於 \(\rm dp\) 的轉移不依賴同一維狀態的轉移,比如這道題的轉移 \(f(i,*)\) 依賴於 \(f(i-1,*)\) ,但是 \(f(i,*)\) 的狀態之間不存在依賴關係。這個也可以計算形如下面的 "\(\rm dp\)"。:

\[f(i) = \min_\

\]設立乙個函式 \(\mathrm(l, r, x, y)\) 用於計算狀態在 \([l,r]\) 之間的所有 \(f\) 值,其中決策點只能在 \([x,y]\) 中找。

分為下面的步驟:

如果 \(w(i,j)\) 的求值時間複雜度為 \(o(1)\) 的,這個分治過程顯然是 \(o(n\log_2 n)\) 的。

但關鍵是現在 \(w(i,j)\) 的計算是 \(o(n)\) 的。

這裡可以採用類似莫隊的雙指標移動,維護 \(w(i,j)\) 。首先可以想到將兩個指標的移動分開計算複雜度。然後就會發現兩個指標移動的次數都是 \(o(n\log_2n)\) 的。

因此一次分治的時間複雜度為 \(o(n\log_2 n)\) ,總的時間複雜度為 \(o(kn \log_2 n)\) 。

#include using namespace std;

typedef long long ll;

const int maxn = 1e5 + 5, maxk = 25;

const ll inf = 1e18;

int n, m, a[maxn];

int cl, cr; ll f[maxk][maxn], cnt[maxn], cw;

inline void upd_cnt(int col, int vl)

ll calc_w(int l, int r)

int cur_m;

void solve(int l, int r, int fl, int fr)

f[cur_m][mid] = res;

solve(l, mid - 1, fl, pos), solve(mid + 1, r, pos, fr);

}int main()

\(\rightarrow\)

\(\rm luogu\) 鏈結

這題兩種方法都可以,不講了。

決策單調性優化DP 分治優化決策單調性

前言 本來這篇已經寫了 frac 了 然後我關機時忘儲存了。華麗的分割線 對於類似於 dp i j max min dp k 1 j 1 count k,i 不妨設 當 最後一次 max min 更新時 f i,j k 若有 forall i,j in 1,n s.t.i j rightarrow ...

單調佇列優化和決策單調性優化

有時狀態轉移方程形如f i j min w i,j 其中l i,j k j,l i,j l i,j 1 如果兩個決策k1,k2滿足f i 1 k1 f i 1 k2 且k1 k2,那麼k1出現後k2就沒用了。維護乙個佇列,按k從小到大存下所有有用的決策,f i 1 k 是單調上公升的。每次加入新決策...

決策單調性

dp min dp w l,r 若 w l,r 滿足 則 dp 滿足四邊形不等式,其決策點 op 滿足 op le op le op 複雜度降至 mathcal o n 2 eg.合併石子 dp min w l,r 若 w l,r 滿足四邊形不等式,則決策具有單調性。對決策區間分治,具體來說,每次求...