title: Decision monotonicity and slope optimization
date : 2021-10-8
Tags: ACM, dynamic programming
author : Linno
Pre knowledge
Quadrilateral inequality
definition
if
letter
number
w
(
x
,
y
)
(
Z
×
Z
→
Z
)
yes
to
∀
a
,
b
,
c
,
d
∈
Z
,
his
in
a
≤
b
≤
c
≤
d
,
all
have
w
(
a
,
d
)
+
w
(
b
,
c
)
≥
w
(
a
,
c
)
+
w
(
b
,
d
)
,
be
call
letter
number
w
full
foot
four
edge
shape
no
etc.
type
If function w(x,y)(\Z) ×\ Z → \ Z) for ∀ a,b,c,d ∈ \ Z, \ \ where a ≤ b ≤ C ≤ D, \ \ all have w(a,d)+w(b,c) ≥ w(a,c)+w(b,d), \ \ then the function w satisfies the quadrilateral inequality
If the function w(x,y)(Z × Z → Z) for ∀ a,b,c,d ∈ Z, where a ≤ b ≤ C ≤ D, there is w(a,d)+w(b,c) ≥ w(a,c)+w(b,d), then the function w satisfies the quadrilateral inequality
inference
if
letter
number
w
(
x
,
y
)
(
Z
×
Z
→
Z
)
yes
to
∀
a
,
b
∈
Z
,
his
in
a
<
b
,
all
have
w
(
a
,
b
+
1
)
+
w
(
a
+
1
,
b
)
≥
w
(
a
,
b
)
+
w
(
a
+
1
,
b
+
1
)
,
be
call
letter
number
w
full
foot
four
edge
shape
no
etc.
type
If function w(x,y)(\Z) ×\ Z → \ Z) for ∀ a,b ∈ \ Z, where a < B, \ \ has w(a,b+1)+w(a+1,b) ≥ w(a,b)+w(a+1,b+1), \ \ then the function w satisfies the quadrilateral inequality
If the function w(x,y)(Z × Z → Z) for ∀ a,b ∈ Z, where a < B, there is w(a,b+1)+w(a+1,b) ≥ w(a,b)+w(a+1,b+1), then the function w satisfies the quadrilateral inequality
If the function w satisfies the quadrilateral inequality, we also call it convex complete monotonicity, or it is a convex function.
Monotonicity of decision
definition
yes to shape as f [ i ] = m i n 0 ≤ j < i ( f [ j ] + w ( j , i ) ) of shape state turn shift square Course , remember p [ i ] by f [ i ] take reach most Small value Time j of value , p [ i ] Namely by f [ i ] of most excellent Decide Policy . as fruit p [ i ] stay [ 1 , n ] upper single transfer no reduce , be call f have have Decide Policy single transfer nature . For shape such as f[i] = min_ For the state transition equation of {0 ≤ j < I} (f [j] + W (j, I)) \ \ note that p[i] is the value of j when f[i] takes the minimum value, and p[i] is the optimal decision of f[i]\ If p[i] is monotonic on [1,n], then f is said to have decision monotonicity\ For the state transition equation such as f[i]=min0 ≤ j < I (f[j]+w(j,i)), note that p[i] is the value of j when f[i] takes the minimum value, and p[i] is the optimal decision of f[i]. If p[i] is monotonic on [1,n], then f is said to have decision monotonicity.
It can also be understood as if w full foot four edge shape no etc. type , be f have have Decide Policy single transfer nature . If w satisfies the quadrilateral inequality, then f has decision monotonicity. If w satisfies the quadrilateral inequality, then f has decision monotonicity.
Prove monotonicity of decision
After the dp transfer equation is obtained, it can be seen intuitively or reduced to a function with w(j,i). See the first citation blog for details.
step
(1) Update to find the first decision point that can cover i location.
(2) Find decision points through dichotomy.
(3) Find a tail that is not completely covered.
Slope optimization
Slope optimization is a derivative algorithm of decision monotonicity. Using slope, decision optimization can be solved in linear time.
KaTeX parse error: Undefined control sequence: \ at position 322:... Time complexity O(nlogn)\ ̲ ̲\ end{cases}
matters needing attention
(1) After writing the dp transfer equation, first judge whether the slope can be optimized (generally exists) f i ∗ f j f_i*f_j Item fi * fj; or Y ( j ) − Y ( j ′ ) X ( j ) − X ( j ′ ) \frac{Y(j)-Y(j')}{X(j)-X(j')} Form of X(j) − X(j ') Y(j) − Y(j'))
(2) There will be errors in the calculation of slope due to rounding down. Therefore, use the slope function to return the type of long double.
(3) When comparing two slopes, try to write equal to, which has a miraculous effect on weight removal. (if there is a key point, it will lead to the slope denominator out of the pot)
(4) The slope is monotonous and moves the pointer violently. The slope is not monotonous and dichotomous to find the answer.
Examples
[NOI2009] poet G
#include<bits/stdc++.h> #define inf 1e18 #define int long long using namespace std; const int maxn=5e5+7; const int mod=1e9+7; int t,n,L,P; int sum[maxn],res[maxn]; int q[maxn],stk[maxn]; //Find each segment of 1~n optimal decision char str[maxn][35]; long double dp[maxn]; long double fpow(long double a,int b){ long double res=1; while(b){ if(b&1) res=res*a; a=a*a; b>>=1; } return res; } inline long double calc(int j,int i){ return dp[j]+fpow(abs(sum[i]-sum[j]+(i-j-1)-L),P); } void init(){ for(int i=1;i<=n;i++){ dp[i]=inf; res[i]=0; } } inline int bs(int a,int b){ //bin_search dichotomy finds that the first decision b is better than decision a if(calc(a,n)<calc(b,n)) return n+1; int l=b,r=n,mid; int ans=-1; while(l<=r){ mid=(l+r)>>1; if(calc(b,mid)<=calc(a,mid)){ ans=mid; r=mid-1; }else l=mid+1; } return ans; } signed main(){ cin>>t; while(t--){ cin>>n>>L>>P; init(); for(int i=1;i<=n;i++){ cin>>str[i]; sum[i]=strlen(str[i])+sum[i-1]; } int head=1,tail=0; q[++tail]=0; dp[0]=0; for(int i=1;i<=n;i++){ while(head<tail&&bs(q[head],q[head+1])<=i) head++; //Make the corresponding area of the head decision point contain i res[i]=q[head]; dp[i]=calc(q[head],i); while(head<tail&&bs(q[tail-1],q[tail])>=bs(q[tail],i))tail--; //Take the decision point at the end of the team as the decision point, and leave the team in a better position than taking i as the decision point q[++tail]=i; //And replace with i } if(dp[n]>inf){ printf("Too hard to arrange\n"); }else{ printf("%lld\n",(long long)dp[n]); int top=0; for(int i=n;i;i=res[i]) stk[++top]=i; stk[++top]=0; for(int i=top-1;i>=1;i--){ int r=stk[i],l=stk[i+1]+1; for(int j=l;j<r;j++) printf("%s ",str[j]); printf("%s\n",str[r]); } } printf("--------------------\n"); } return 0; }
[HNOI2008] toy packing (Introduction to slope optimization)
#include<bits/stdc++.h> #define inf 0x3f3f3f3f #define int long long #define ld long double using namespace std; const int maxn=5e4+7; int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;} int n,L,head=1,tail=0,tmp; int Q[maxn],S[maxn],dp[maxn]; inline int X(int x){return S[x];} inline int Y(int x){return dp[x]+(S[x]+L)*(S[x]+L);} inline ld slope(int a,int b){ return (ld)(Y(a)-Y(b))/(X(a)-X(b)); } signed main(){ n=read();L=read(); ++L; memset(S,0,sizeof(S)); for(int i=1;i<=n;i++) S[i]=read()+S[i-1]+1; Q[++tail]=0; for(int i=1;i<=n;i++){ while(head<tail&&slope(Q[head],Q[head+1])<=2*S[i]) ++head; tmp=Q[head]; //Decision point dp[i]=dp[tmp]+(S[i]-S[tmp]-L)*(S[i]-S[tmp]-L); while(head<tail&&slope(Q[tail-1],Q[tail])>=slope(Q[tail-1],i)) --tail; Q[++tail]=i; } printf("%lld",dp[n]); return 0; }
[SDOI2012] task arrangement
#include<bits/stdc++.h> #define inf 0x3f3f3f3f #define int long long #define db long double using namespace std; const int maxn=300007; const int mod=1e9+7; int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;} int n,S,t[maxn],c[maxn]; int q[maxn],dp[maxn]; int L,R; int solve(int val){ int l=L,r=R-1,ans=-1; while(l<=r){ int m=(l+r)>>1; if((dp[q[m+1]]-c[q[m+1]]*S-dp[q[m]]+c[q[m]]*S)>val*(c[q[m+1]]-c[q[m]]))ans=m,r=m-1; else l=m+1; } if(ans==-1)return q[R]; return q[ans]; } signed main(){ n=read(); S=read(); memset(dp,inf,sizeof(dp)); dp[0]=0;q[0]=0; for(int i=1;i<=n;i++){ t[i]=read()+t[i-1]; c[i]=read()+c[i-1]; } L=0,R=0; for(int i=1;i<=n;i++){ int j=solve((db)t[i]); dp[i]=dp[j]+t[i]*(c[i]-c[j])+S*(c[n]-c[j]); while(L<R&&(dp[q[R]]-c[q[R]]*S-dp[q[R-1]]+c[q[R-1]]*S)*(c[i]-c[q[R]])>=(dp[i]-c[i]*S-dp[q[R]]+c[q[R]]*S)*(c[q[R]]-c[q[R-1]])) R--; q[++R]=i; } cout<<dp[n]<<"\n"; return 0; }
[CEOI2004] site selection of sawmill
#include<cstdio> #include<cstring> #include<algorithm> #define db double using namespace std; const int M=3e4+1; int n; int q[M],fi,la,ans=2e9+1; int sum,s[M],d[M],w[M]; db calc(int j,int k){return 1.0*(d[j]*s[j]-d[k]*s[k])/(s[j]-s[k]);} int count(int i,int j){return sum-d[j]*s[j]-d[i]*(s[i]-s[j]);} int main() { scanf("%d",&n); for(int i=1;i<=n;i++){scanf("%d%d",&w[i],&d[i]);} for(int i=n;i>=1;i--) d[i]+=d[i+1]; for(int i=1;i<=n;i++) s[i]=s[i-1]+w[i],sum+=d[i]*w[i]; for(int i=1;i<=n;i++){ while(fi<la&&calc(q[fi],q[fi+1])>d[i]) ++fi; ans=min(ans,count(i,q[fi])); while(fi<la&&calc(q[la-1],q[la])<calc(q[la],i)) --la; q[++la]=i; } printf("%d\n",ans); return 0; }
Pit to be filled
Overall partition
SMAWK algorithm
Optimization of quadrilateral inequality for interval dp
reference material
https://www.cnblogs.com/birchtree/p/12937975.html
https://www.cnblogs.com/Xing-Ling/p/11210179.html
https://alan-sp.github.io/post/jue-ce-dan-diao-xing-xue-xi-bi-ji/
https://www.cnblogs.com/kebingyi/p/14157680.html