四边形不等式例题完整解析(不加推导)

P4767 [IOI2000]邮局

dp方程:

dp[i][j]=min{dp[k][j−1]+w(k+1,i)},k∈[0,i)

#include<bits/stdc++.h>
#define MAXN 3010
#define N 310

using namespace std;

int V,P,X[MAXN],dp[MAXN][N];

int w(int l,int r) {
	int mid=l+r>>1,ans=0;
	for(int i=l;i<mid;i++) ans+=X[mid]-X[i];
	for(int i=mid+1;i<=r;i++) ans+=X[i]-X[mid];
	return ans;
}

int main() {
	cin>>V>>P;
	for(int i=1;i<=V;i++) cin>>X[i];
	
	sort(X+1,X+V+1);
	memset(dp,0x3f,sizeof(dp));
	dp[0][0]=0;
	for(int j=1;j<=P;j++) {
		for(int i=1;i<=V;i++) {
			for(int k=0;k<i;k++) {
				dp[i][j]=min(dp[k][j-1]+w(k+1,i),dp[i][j]);
			}
		}
	}

	cout<<dp[V][P]<<endl;
	
	return 0;
}

我们发现对于w的预处理是n2的,而dp是n3的,很明显过不了数据,考虑优化;

发现w是可以递归预处理的,时间复杂度n^3

#include<bits/stdc++.h>
#define MAXN 3010
#define N 310

using namespace std;

int V,P,X[MAXN],dp[MAXN][N],w[MAXN][MAXN];

void init() {
	for(int l=1;l<=V;l++) {
		w[l][l]=0;
		for(int r=l+1;r<=V;r++) {
			w[l][r]=w[l][r-1]+X[r]-X[l+r>>1];
		}
	}
}

int main() {
	cin>>V>>P;
	for(int i=1;i<=V;i++) cin>>X[i];
	
	init();
	sort(X+1,X+V+1);
	memset(dp,0x3f,sizeof(dp));
	dp[0][0]=0;
	for(int j=1;j<=P;j++) {
		for(int i=1;i<=V;i++) {
			for(int k=0;k<i;k++) {
				dp[i][j]=min(dp[k][j-1]+w[k+1][i],dp[i][j]);
			}
		}
	}

	cout<<dp[V][P]<<endl;
	
	return 0;
}

发现没有什么别的方法可以优化了, 而且还是过不了数据范围,并且dp式子和四边形不等式的模板式特别像,我们先大胆猜测一下这个题用的是四边形不等式,打表来看一下w是否具有决策单调性

#include<bits/stdc++.h>
#define MAXN 3010
#define N 310

using namespace std;

int V,P,X[MAXN],dp[MAXN][N],w[MAXN][MAXN];

void init() {
	for(int l=1;l<=V;l++) {
		w[l][l]=0;
		for(int r=l+1;r<=V;r++) {
			w[l][r]=w[l][r-1]+X[r]-X[l+r>>1];
		}
	}
}

int main() {
	cin>>V>>P;
	for(int i=1;i<=V;i++) cin>>X[i];
	
	init();
	sort(X+1,X+V+1);
	memset(dp,0x3f,sizeof(dp));
	dp[0][0]=0;
	for(int j=1;j<=P;j++) {
		for(int i=1;i<=V;i++) {
			for(int k=0;k<i;k++) {
				if(dp[i][j]>dp[k][j-1]+w[k+1][i])
				cout<<k<<" ";
				dp[i][j]=min(dp[k][j-1]+w[k+1][i],dp[i][j]);
			}
			cout<<'\n';
		}
	}

	cout<<dp[V][P]<<endl;
	
	return 0;
}
10 5
1 2 3 6 7 9 11 22 44 50
0
0
0
0
0
0
0
0
0
0

1
1
1 3
1 2 3
1 2 3
1 2 3
1 2 3 7
1 2 3 4 6 7 8
1 2 3 4 5 6 7 8


2
2 3
2 3
2 3 5
2 3 4 5
2 3 4 5 7
2 3 4 5 6 7 8
2 3 4 5 6 7 8



3
3
3 5
3 4 5 6
3 4 5 6 7
3 4 5 6 7 8
3 4 5 6 7 8




4
4 5
4 5 6
4 5 6 7
4 5 6 7 8
4 5 6 7 8 9
9

发现决策转移点k的确具有单调性,那么表示dp式子也具有决策单调性,但是由于本人太菜,什么都不会推,所以我们直接来试一下哪种范围是正确的
//范围无外乎有两种:
s[i+1][j]<=s[i][j]<=s[i][j-1]
s[i][j-1]<=s[i][j]<=s[i+1][j]

发现符合第二个式子(也就是说用第二个式子可以推出正确答案)

至此,即使我们不会四边形不等式,这道题依旧完美AC~~

posted @ 2021-03-16 16:55  yxr~  阅读(98)  评论(0编辑  收藏  举报