我是靠谱客的博主 愤怒小兔子,最近开发中收集的这篇文章主要介绍动态规划--数塔问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

动态规划–数塔问题

今天学习了动态规划的数塔问题,老师给我们讲了三种方法。在这里插入图片描述
(1)第一种方法是原始的递归,就是从上往下看一个n层塔的最大路径问题可以转化为选出左右两个n-1层塔的最大路径问题的较大值,即:f(n)=max{ f(左,n-1), f(右,n-1) },依次向下直到第n层。

左边n-1数塔问题左边n-1数塔问题

右边n-1数塔问题右边n-1数塔问题

int f1(int i, int j){
	if(i < n-1)	
		return data[i][j] + max(f1(i+1,j),f1(i+1,j+1));
	else
		return data[i][j];
}

考虑到每次在计算是都会出现重复,因此有了方法二。

重复计算的区域
重复计算的区域
(2)第二种方法是对第一种方法的改进。把计算的结果放到一个数组里面就不会重复计算了。

int f2(int i,int j){
	if(i < n-1){
		if(d[i][j] == 0){
			d[i][j] = data[i][j] + max(f1(i+1,j),f1(i+1,j+1));
		}
		return d[i][j];
	}
	else
		return data[i][j];
	
}

(3)第三种方法没有用递归,从下往上考虑在这里插入图片描述

  1. 一个底层为19、7、10、4、16的n层数塔问题就可以看成一个底层为21、28、19、21的n-1层数塔问题
  2. 而对于每一层只需要考虑自己下面连接的左右两边哪个数大,就用自身的值加上这个较大值来更新自身的值。
for(i = n-2;i>=0;i--){
		for(j = 0;j<=i;j++){
			data[i][j] = data[i][j] + max(data[i+1][j],data[i+1][j+1]);
		}
	}
	printf("路径上值最大为:%d",data[0][0]);

总结:1、相比之下我更喜欢第三种方法,因为它既不用写递归函数也没有重复计算,而且不需要用两个数组。而且第一种方法只能得到最大值,但是无法得到最大路径。
2、要得到最大路径,需要从上往下推。

printf("最优路径为:%d",data[0][0]);
	j = 0;
	for(i = 1;i<n;i++){
		if(d[i][j]>d[i][j+1]){
			printf("-> %d",data[i][j]);
		}
		else{
			printf("-> %d",data[i][j+1]);
			j = j + 1;
		}		
	}

最优路径
最优路径
全部代码:(记得在用一种方法的时候把其他两个注释掉)

#include<stdio.h>
const int n = 5;
int data[n][n] = {0};
int d[n][n] = {0};
int max(int x,int y){
	if(x>y)	return x;
	else	return y;
}
int f1(int i, int j){
	if(i < n-1)		return data[i][j] + max(f1(i+1,j),f1(i+1,j+1));
	else	return data[i][j];
}

int f2(int i,int j){
	if(i < n-1){
		if(d[i][j] == 0){
			d[i][j] = data[i][j] + max(f1(i+1,j),f1(i+1,j+1));
		}
		return d[i][j];
	}
	else	return data[i][j];
	
}
int main(){
	int i,j;
	printf("请依次输入数塔各顶点的值:n"); 
	for(i = 0;i<n;i++){
		for(j = 0;j<=i;j++){
			scanf("%d",&data[i][j]);
		}
	}
	/方法一:从上到下,递归 
//	printf("路径上值最大为:%d",f1(0,0));
	/方法二:从上到下,加存储(备忘录法)
//	printf("路径上值最大为:%d",f2(0,0));
	/方法三:从下到上,阶段划分(填表法) 
	for(j = 0;j<n;j++){
		d[n-1][j] = data[n-1][j];
	}
	for(i = n-2;i>=0;i--){
		for(j = 0;j<=i;j++){
			d[i][j] = data[i][j] + max(d[i+1][j],d[i+1][j+1]);
		}
	}
	printf("路径上值最大为:%dn",d[0][0]);
	
	//得出最优路径
	
	printf("最优路径为:%d",data[0][0]);
	j = 0;
	for(i = 1;i<n;i++){
		if(d[i][j]>d[i][j+1]){
			printf("-> %d",data[i][j]);
		}
		else{
			printf("-> %d",data[i][j+1]);
			j = j + 1;
		}		
	}
	return 0;
} 

最后

以上就是愤怒小兔子为你收集整理的动态规划--数塔问题的全部内容,希望文章能够帮你解决动态规划--数塔问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(57)

评论列表共有 0 条评论

立即
投稿
返回
顶部