【總結】從詩人小G談DP的四邊形不等式優化
阿新 • • 發佈:2018-12-19
四邊形不等式
設是定義在整數集合上的二元函式。若對於定義域上的任何整數,,。則稱函式滿足四邊形不等式。
一維DP的決策單調性
對於一維線性狀態轉移方程:
若函式滿足四邊形不等式,則稱具有決策單調性。
而在bzoj1563詩人小G中,轉移方程如下:
設表示前句是排版後最小不協排程,為第句詩的長度,為前句詩的總長度+。
,可以按奇偶分類求導證明得到:(懶,這裡就不具體證明了)
而對於這類決策單調性的線性轉移問題,可以記錄每一個所管理的最優決策區間,在具體處理時,用單調佇列儲存三元組(表示最優決策點,,表示其所管理的區間),佇列中按升序排列,處理到時首先彈出的,然後取隊首更新,彈出隊尾不優的,二分插入即可。
複雜度。具體實現可以參照程式碼。
#include<bits/stdc++.h>
using namespace std;
typedef long double ld;
const int N=1e5+10;
const ld nf=1e18;
int n,len,pw,hd,tl,to[N],TK,T,sum[N];
ld dp[N];
char s[N][32];
struct P{
int st,l,r;
P(int st_=0,int l_=0,int r_=0):st(st_),l(l_),r(r_){};
}q[N],ori;
inline ld fp(int x)
{
register ld re=1;
for(register int i=pw;i;--i) re*=x;
return re;
}
inline ld cal(int a,int b)
{return dp[a]+fp(abs(sum[b]-sum[a]-1-len));}
inline void sol()
{
register int i,j,L,R,mid,ans;
scanf("%d%d%d",&n,&len,&pw);
for(i=1;i<=n;++i) {
scanf("%s",s[i]);
sum[i]=sum[i-1]+strlen(s[i])+1;
}
hd=tl=0;q[hd]=ori=P(0,1,n);
for(i=1;i<=n;++i){
for(;q[hd].r<i;++hd) q[hd]=ori;
to[q[hd].st]=i;dp[i]=cal(q[hd].st,i);
for(;cal(i,q[tl].l)<cal(q[tl].st,q[tl].l);--tl) q[tl]=ori;
L=q[tl].l;R=q[tl].r;j=q[tl].st;ans=L;
for(;L<=R;){
mid=(L+R)>>1;
if(cal(j,mid)<=cal(i,mid)) L=(ans=mid)+1;
else R=mid-1;
}
if(ans<n){
q[tl].r=ans;
q[++tl]=P(i,ans+1,n);
}
}
if(dp[n]>nf) puts("Too hard to arrange");
else printf("%lld\n",(long long)(dp[n]+0.5));
printf("--------------------\n");
}
int main(){
hd=0;tl=1;
scanf("%d",&T);
for(TK=1;TK<=T;++TK) sol();
return 0;
}
二維DP的優化
對於區間中的二維狀態轉移方程:
若滿足四邊形不等式,且對於任意的,,那麼也滿足四邊形不等式。(證明要用到數學歸納法)
設的最優決策為
當滿足四邊形不等式時,對於任意,
而石子合併的DP方程為:
顯然是滿足四邊形不等式的(取到等號),所以求時,只需要列舉即可。
總複雜度為。原列舉複雜度
p.s.
證明什麼的,哪天心情好再補吧。ヾ(◍°∇°◍)ノ゙