石子合并(一排的和一个环的)

石子合并

石子合并是环形dp的经典题,要做它我们首先要做它的弱化版,也就是排成一排的情况:石子合并(弱化版)(洛谷p1775)

石子合并弱化版解法

对于这道题,可以先从简单的情况开始考虑;比如现在要合并a,b,c三堆石子,那么显然只有先合并a,b两队石子和先合并b,c两队石子两种情况,也就是说:

\[f[1][3]=min(f[1][2]+f[3][3],f[1][1]+f[2][3])+v[1][3]; \]

\[//f[i][j]表示合并第i到第j堆石子所要花费的代价,v[i][j]表示第i到j堆石子的总质量 \]

同样的,对于4堆石子a,b,c,d,可以先合并b,c,d,也可以先合并a,b,也可以先合并a,b,c,即可以从a,b,c,d之间的三个空隔中的任意一个隔开,将石子分成两堆,然后分别合并两堆,最后找代价的最小值;

于是就可以得到这样的一个dp思路:枚举一个L表示合并的区间长度从1到n(n是石子堆数),然后在每一个区间内再枚举断点k,求出每个区间所用代价的最小值,最后的答案落在区间[1,n];这种通过短区间转移到大区间的dp思路就是区间dp;

代码如下:

#include<bits/stdc++.h>
using namespace std;
int n,m[305],f[305][305],v[305][305];//f和V的含义同上
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>m[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=i;j<=n;j++){
			v[i][j]=v[i][j-1]+m[j];//处理出所有区间的石子重量和
		}
	}
	for(int l=1;l<n;l++){//枚举区间长度
		for(int i=1;i<=n-l;i++){
			int j=i+l;
			f[i][j]=0x3f3f3f3f;
			for(int k=i;k<j;k++){//枚举断点
				f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+v[i][j]);//转移方程
			}
		}
	}
	cout<<f[1][n];//答案落在区间[1,n]
	return 0;
}

石子合并

p1880
接下来就可以怎么把刚才的做法变成环形的,显然最容易想到的做法就是破环为链,这样就可以套用刚才的做法了;但是如果这样做就需要枚举在原序列的每一个点上破环得到的结果,时间复杂度无法接受;

其实可以想到这样一种思路:同样是破环为链,但是我可以保证只在破环之后的这个新序列上做一次区间dp可以覆盖到所有情况;有没有这样的处理方法呢?显然是有的:把原序列复制一遍接到它后面就可以了;比如对于序列4 7 3 5,处理之后的新序列就是4 7 3 5 4 7 3 5;可以发现新序列上每一个长度为4的区间就是破环为链的一种结果;

代码如下:

#include<bits/stdc++.h>
using namspace std;
int n,m[210],f[210][210],v[210][210],f2[210][210];//f是最小值,f2是最大值
int main(){
	int ans1=0x3f3f3f3f,ans2=-0x3f3f3f3f;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>m[i];
	}
	for(int i=n+1;i<=n+n;i++){//复制一遍原序列
		m[i]=m[i-n];
	}
	for(int i=1;i<=n+n;i++){
		for(int j=i;j<=n+n;j++){
			v[i][j]=v[i][j-1]+m[j];
		}
	}
	for(int l=1;l<n;l++){//枚举的区间长度仍然是原序列的长度
		for(int i=1;i<=n+n-l;i++){
			int j=i+l;
			f[i][j]=0x3f3f3f3f;
			f2[i][j]=-0x3f3f3f3f;
			for(int k=i;k<j;k++){
				f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+v[i][j]);
				f2[i][j]=max(f2[i][j],f2[i][k]+f2[k+1][j]+v[i][j]);//相同的转移方法
			}
		}
	}
	for(int i=1;i<=n;i++){//求出所有情况的最值
		ans1=min(ans1,f[i][i+n-1]);
		ans2=max(ans2,f2[i][i+n-1]);
	}
	cout<<ans1<<endl<<ans2;
	return 0;
}
posted @ 2025-09-27 12:09  Turkey_VII  阅读(14)  评论(0)    收藏  举报