HRBUST 1818/1819 石子合并问题--直线版 /圆形版(经典动态规划)

石子合并问题(直线版)

一条直线上摆放着一行共n堆的石子。现要将石子有序地合并成一堆。规定每次只能选相邻的两堆合并成新的一堆,并将新的一堆石子数记为该次合并的得分。请编辑计算出将n堆石子合并成一堆的最小得分和将n堆石子合并成一堆的最大得分。

Input

输入有多组测试数据。

每组第一行为n(n<=100),表示有n堆石子,。

二行为n个用空格隔开的整数,依次表示这n堆石子的石子数量ai(0

Output

每组测试数据输出有一行。输出将n堆石子合并成一堆的最小得分和将n堆石子合并成一堆的最大得分。 中间用空格分开。

Sample Input

3

1 2 3

Sample Output

9 11

题解:经典的区间DP题。

以求最小值为例:

状态dp[i][j]:i到j的合并最小值。

状态转移方程:dp[i][j]=min(dp[i][j],dp1[i][k]+dp[k+1][j]+num[j]-num[i-1])。

num[i]表示前i个元素的和。

答案:dp[1][n]。

PS:dp[i][j]要初始化为无穷大,但是当i==j时,要初始化为0。因为当按照i,j去遍历的话,当求dp[i][j]的时候,i=k,dp[i][k]是没有意义的,所有要dp[i][i]=0。当求dp[i][j]的时候还有一个问题就是dp[k+1][j]可能还是没有求出来的,所有不能按照这样去遍历。可以按照区间的长度len去遍历,j=len+i-1.

具体代码如下:

#include
#define INF 0x3f3f3f3f//无穷大
using namespace std;
int dp1[102][102];//最小 
int dp2[102][102];//最大 
int n;
void init()
{
	for(int i=0;i<=n;i++)
		for(int j=0;j<=n;j++)
			if(i==j)
			{
				dp1[i][j]=0;
				dp2[i][j]=0;
			}
			else
			{
				dp1[i][j]=INF;
				dp2[i][j]=0; 
			}			
}
int max(int a,int b)
{
	return a>b?a:b;
}
int min(int a,int b)
{
	return a>n)
	{
		init();
		int i,j,k,len;
		int num[102]={0};//前i项和 
		int a;
		for(i=1;i<=n;i++)
		{
			cin>>a;
			num[i]=num[i-1]+a;
		}
		for(len=2;len<=n;len++)
			for(i=1;i

石子合并问题(圆形版)

题目跟直线版就改变了一小点,就是将石子铺在圆形轨道上,求最大值,最小值。

题解:博主的方法有点偏暴力。将直线连着铺两次在一条直线上,就转化成了直线版了。算出从1到2n的dp值,再比较出所有区间长度为n的dp的最大或最小值。区间长度为n的一共为n组。

具体代码如下:

#include
#define INF 0x3f3f3f3f
using namespace std;
int dp1[204][204];//最小 
int dp2[204][204];//最大 
int n;
void init()
{
	for(int i=0;i<=n*2;i++)
		for(int j=0;j<=n*2;j++)
		{
			if(i==j)
			{
				dp1[i][j]=0;		
				dp2[i][j]=0; 
			}
			else{
				dp1[i][j]=INF;			
				dp2[i][j]=0;
			}			 
		}
}
int max(int a,int b)
{
	return a>b?a:b;
}
int min(int a,int b)
{
	return a>n)
	{
//		init();
		int i,j,k,len;
		int num[204]={0};//前i项和 
		int a[204];
		a[0]=0;
		for(i=1;i<=n;i++)
		{
			cin>>a[i];
			num[i]=num[i-1]+a[i];
		}
		for(j=1;j<=n;j++)
		{
			num[i]=num[i-1]+a[j];
			i++;
		}
		for(len=2;len<=n*2;len++)//区间长度要变 
			for(i=1;idp2[i][i+n-1]?MAX:dp2[i][i+n-1];
			MIN=MIN

 

你可能感兴趣的:(算法-动态规划)