[learning notes of algorithm competition] decision monotonicity and slope optimization - super useful detailed explanation of DP

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

Tags: C++ Programming Algorithm Dynamic Programming ICPC

Posted on Thu, 28 Oct 2021 14:28:39 -0400 by illushinz