动态规划【数塔初始篇之一】(原创)

6033290

【数塔】杭电2084

http://acm.hdu.edu.cn/showproblem.php?pid=2084

1.用递归的方法如下:

#include<stdio.h>
#define MAX_LEN 101
#define MAX(x,y) ((x > y) ? x : y )//计算两个数的最大值
int N,num[MAX_LEN][MAX_LEN];

int MaxSum(int i, int j)
{
	if(i==N-1)//假如计算到最后一行,就直接返回
	{
		return num[i][j];
	}
	else//否则,计算该数下方临近的两个值,取大者
	{
		return num[i][j] + MAX(MaxSum(i+1,j), MaxSum(i+1,j+1));
	}
}
int main()
{
	int t,i,j;
	scanf("%d", &t);
	while((t--) && scanf("%d", &N))
	{
		for(i=0; i<N; i++)
		{
			for(j=0; j<=i; j++)
			{
				scanf("%d", &num[i][j]);//将数据读入二维数组
			}
		}
		printf("%d\n", MaxSum(0,0));//递归计算数塔的最大值
	}
	return 0;
}

经过实验发现,计算的效率很不理想!为什么会这样?我们不妨简单的分析一下:

假如我们计算一个数MaxSum(i,j),就要调用函数,计算MaxSum(i+1,j)和MaxSum(i+1,j+1),比较二者的大小,取大者加上num[i][j]返回。只要稍微观察,我们就会发现,在计算MaxSum (i,j+1)的时候,又再一次调用MaxSum(i+1,j+1),重复计算就是这样产生的。

这样的例子你可能感觉不出什么,我们不妨将每调用一次MaxSum(i,j)称作在(i,j)位置上的一次计算,这样我们能得到一个调用次数的数塔:

1

1 1

1 2 1

1 3 3 1

1 4 6 4 1

1 5 10 10 5 1

……

怎么样?是不是很熟?没错,就是传说中的杨辉三角!

计算一下总和:20+21+22+……+2N-1

这是多大的一个数……我想就不用我说了吧……

难道这道题不能用递归计算么?那倒也不是,只需我们将中间算过的数值保存即可……

#include<stdio.h>
#include<memory.h>
#define MAX_LEN 101
#define MAX(x,y) ((x > y) ? x : y )//计算两个数的最大值
int N;
int num[MAX_LEN][MAX_LEN];
int num_temp[MAX_LEN][MAX_LEN];

int MaxSum(int i, int j)
{
	if(i==N-1)//假如计算到最后一行,就直接返回
	{
		return num[i][j];
	}
	else//否则,计算该数下方临近的两个值,取大者
	{
		if(-1==num_temp[i+1][j])//如果没计算过,就计算出结果并保留
		{
			num_temp[i+1][j] = MaxSum(i+1,j);
		}
		if(-1==num_temp[i+1][j+1])//如果没计算过,就计算出结果并保留
		{
			num_temp[i+1][j+1] = MaxSum(i+1,j+1);
		}
		return num[i][j] + MAX(num_temp[i+1][j], num_temp[i+1][j+1]);
	}
}
int main()
{
	int t,i,j;
	scanf("%d", &t);
	while((t--) && scanf("%d", &N))
	{
		memset(num_temp,-1,sizeof(num_temp));//初始化
		for(i=0; i<N; i++)
		{
			for(j=0; j<=i; j++)
			{
				scanf("%d", &num[i][j]);//将数据读入二维数组
			}
		}
		printf("%d\n", MaxSum(0,0));//递归计算数塔的最大值
	}
	return 0;
}

书上说:这种将一个问题分解成子问题递归求解,并且将中间结果保存避免重复计算的办法,就叫做“动态规划”。动态规划通常是用来求最优解的问题,能用动态规划求解的最优解问题,必须满足最优解每个局部解也都是最优的。以上题为例,最佳路径上面的每个数字到达底部都是最佳路径。

综上,我们可以发现动态规划就是一种递归的体现,它一种更加高效的递归方式,高效在于动态规划以空间换效率,保留了中间变量的值,从而减少大量的重复运算!个人觉得,动态规划是一种更加复杂的递归方式!

posted on 2010-02-24 14:04  W_Z_C  阅读(273)  评论(0)    收藏  举报

导航