【CF868F】Yet Another Minimization Problem (决策单调性优化dp+分治)
description
點擊查看題目
solution
code
設(shè)dpi,jdp_{i,j}dpi,j?:把前iii個數(shù)劃分jjj段的最小花費,wi,jw_{i,j}wi,j?:[i,j][i,j][i,j]劃分為一段的花費
dpi,j=min(dp[k][j?1]+w[k+1][i]),k<idp_{i,j}=min(dp[k][j-1]+w[k+1][i]),k<idpi,j?=min(dp[k][j?1]+w[k+1][i]),k<i
而這個轉(zhuǎn)移是具有決策單調(diào)性的
換言之,?i1<i2\forall i_1<i_2?i1?<i2?,且i1i_1i1?由k1k_1k1?轉(zhuǎn)移而來,i2i_2i2?由k2k_2k2?轉(zhuǎn)移而來,則必有k1≤k2k_1\le k_2k1?≤k2?
證明一下,假設(shè)k1>k2k_1>k_2k1?>k2?
由條件可以列得
{dp(k1,j?1)+w(k1+1,i1)≤dp(k2,j?1)+w(k2+1,i)dp(k2,j?1)+w(k2+1,i2)≤dp(k1,j?1)+w(k1+1,i)\left\{ \begin{aligned} dp(k_1,j-1)+w(k_1+1,i_1) \le dp(k_2,j-1)+w(k_2+1,i)\\ dp(k_2,j-1)+w(k_2+1,i_2)\le dp(k_1,j-1)+w(k_1+1,i)\\ \end{aligned} \right. {dp(k1?,j?1)+w(k1?+1,i1?)≤dp(k2?,j?1)+w(k2?+1,i)dp(k2?,j?1)+w(k2?+1,i2?)≤dp(k1?,j?1)+w(k1?+1,i)?
假設(shè)兩個式子都是取的===,那么交換k1,k2k_1,k_2k1?,k2?不影響
否則至少有一個取了<<<,不防假設(shè)
{dp(k1,j?1)+w(k1+1,i1)≤dp(k2,j?1)+w(k2+1,i)dp(k2,j?1)+w(k2+1,i2)<dp(k1,j?1)+w(k1+1,i)\left\{ \begin{aligned} dp(k_1,j-1)+w(k_1+1,i_1) \le dp(k_2,j-1)+w(k_2+1,i)\\ dp(k_2,j-1)+w(k_2+1,i_2)< dp(k_1,j-1)+w(k_1+1,i)\\ \end{aligned} \right. {dp(k1?,j?1)+w(k1?+1,i1?)≤dp(k2?,j?1)+w(k2?+1,i)dp(k2?,j?1)+w(k2?+1,i2?)<dp(k1?,j?1)+w(k1?+1,i)?
移項得
{w(k1+1,i1)?w(k2+1,i1)≤dp(k2,j?1)?dp(k1,j?1)dp(k2,j?1)?dp(k1,j?1)<w(k1+1,i2)?w(k2+1,i2)\left\{ \begin{aligned} w(k_1+1,i_1)-w(k_2+1,i_1) \le dp(k_2,j-1)-dp(k_1,j-1)\\ dp(k_2,j-1)-dp(k_1,j-1)< w(k_1+1,i_2)-w(k_2+1,i_2)\\ \end{aligned} \right. {w(k1?+1,i1?)?w(k2?+1,i1?)≤dp(k2?,j?1)?dp(k1?,j?1)dp(k2?,j?1)?dp(k1?,j?1)<w(k1?+1,i2?)?w(k2?+1,i2?)?
所以有
w(k1+1,i1)?w(k2+1,i1)<w(k1+1,i2)?w(k2+1,i2)w(k_1+1,i_1)-w(k_2+1,i_1)< w(k_1+1,i_2)-w(k_2+1,i_2)w(k1?+1,i1?)?w(k2?+1,i1?)<w(k1?+1,i2?)?w(k2?+1,i2?)
再移項,最后得
w(k2+1,i1)?w(k1+1,i1)>w(k2+1,i2)?w(k1+1,i2)w(k_2+1,i_1)-w(k_1+1,i_1)> w(k_2+1,i_2)-w(k_1+1,i_2)w(k2?+1,i1?)?w(k1?+1,i1?)>w(k2?+1,i2?)?w(k1?+1,i2?)
這顯然是不成立的,因為i1<i2i_1<i_2i1?<i2?,而www是跟區(qū)間內(nèi)相同權(quán)值的個數(shù)組合數(shù)有關(guān)
不等號右邊的增長應(yīng)更快,假設(shè)不成立;證明的確具有決策單調(diào)性
分治處理,注意決策點可能并不一定是正中間,可能會有所偏移,直接枚舉即可
#include <cstdio> #include <cstring> #define inf 1e18 #define maxn 100005 #define int long long int n, K, k, curl = 1, curr, cost; int a[maxn], cnt[maxn]; int dp[maxn][25];void Delete( int x ) {cost = cost - cnt[a[x]] + 1;cnt[a[x]] --; }void Add( int x ) {cost = cost + cnt[a[x]];cnt[a[x]] ++; }void calc( int l, int r ) {while( curl < l ) Delete( curl ++ );while( l < curl ) Add( -- curl );while( curr < r ) Add( ++ curr );while( r < curr ) Delete( curr -- ); }//計算[L,R]區(qū)間的dp值 決策點枚舉范圍為[l,r] void solve( int L, int R, int l, int r ) {if( L > R || l > r ) return;int mid = ( L + R ) >> 1, pos, ans = inf;for( int i = l;i <= r;i ++ ) {calc( i + 1, mid );if( ans > dp[i][k - 1] + cost ) ans = dp[i][k - 1] + cost, pos = i;}dp[mid][k] = ans;solve( L, mid - 1, l, pos );solve( mid + 1, R, pos, r ); }signed main() {memset( dp, 0x7f, sizeof( dp ) );dp[0][0] = 0;scanf( "%lld %lld", &n, &K );for( int i = 1;i <= n;i ++ )scanf( "%lld", &a[i] );for( k = 1;k <= K;k ++ ) solve( 1, n, 0, n - 1 );//決策點i表示[j,i]為一個子段,[i+1,k]為一個子段//所以決策點范圍是[0,n-1]而不是[1,n]printf( "%lld\n", dp[n][K] );return 0; }總結(jié)
以上是生活随笔為你收集整理的【CF868F】Yet Another Minimization Problem (决策单调性优化dp+分治)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 惠普笔记本电脑如何对电池进行检测
- 下一篇: 交换机安装