三角形问题——(递归,递推,动态规划)

1. 用递归的方法来解决这个问题

2. 带记忆的递归(将那些已经计算过的点直接返回值)这里递归的时候,将那些计算过在它之下的最大路径的值保存起来,下次

再用的时候直接查看就可以了

#include<iostream>
#include <vector>
#include <string>
using namespace std;

#define MAXLINE 100
int vec[MAXLINE][MAXLINE];
int maxsum[MAXLINE][MAXLINE];
int ifmaxsum[MAXLINE][MAXLINE];

#define N 4

int max_sum(int a,int b)
{
	if(a>=b)
		return a;
	else
		return b;
}
int big_sum(int i,int j)
{
	if(i==N)
		return vec[i][j];
	return max_sum(big_sum(i+1,j),big_sum(i+1,j+1))+vec[i][j];
}

//2. 带记忆的递归(将那些已经计算过的点直接返回值)
//这里递归的时候,将那些计算过在它之下的最大路径的值保存起来,下次
//再用刀的时候直接查看就可以了。
int big_sum1(int i,int j)
{
	if(ifmaxsum[i][j]==-1)
		return maxsum[i][j];
	if(i==N)
		return vec[i][j];
	else
	{
		int x,y;
		x=big_sum1(i+1,j);
		y=big_sum1(i+1,j+1);
		maxsum[i][j]=max_sum(x,y)+vec[i][j];
		ifmaxsum[i][j]=-1;
		return maxsum[i][j];
	}
}
int main()
{
	vec[0][0]=7;
	vec[1][0]=3,vec[1][1]=8;
	vec[2][0]=8,vec[2][1]=1;vec[2][2]=0;
	vec[3][0]=2,vec[3][1]=7,vec[3][2]=4,vec[3][3]=4;
	vec[4][0]=4,vec[4][1]=5,vec[4][2]=2,vec[4][3]=6,vec[4][4]=5;

	cout<<big_sum(0,0)<<endl;
	cout<<big_sum1(0,0)<<endl;
}

3. 从最下面的一行开始往上面求最大值,这样可以一直往上面递推来求最大路径值

4. 空间的优化,没一行求完之后就没有用了,可以只用一行数组

#include<iostream>
#include <vector>
#include <string>
#include <math.h>
using namespace std;

#define MAXLINE 100
int vec[MAXLINE][MAXLINE];

//从最下面的一行开始往上面求最大值,这样可以一直往上面递推来求最大路径值
int DiTui(int vec[][MAXLINE],int n)
{
	int temp[MAXLINE][MAXLINE];
	if(n==1)
		return vec[0][0];

	for(int j=0;j<=n-1;j++)
		temp[n-1][j]=vec[n-1][j];
	for(int i=n-2;i>0;i--)
		for(int j=0;j<=i;j++)
			temp[i][j]=max(temp[i+1][j],temp[i+1][j+1])+vec[i][j];
	return vec[0][0]+max(temp[1][0],temp[1][1]);
}
//空间的优化,没一行求完之后就没有用了,可以只用一行数组
int DiTui1(int vec[][MAXLINE],int n)
{
	int temp[MAXLINE];
	if(n==1)
		return vec[0][0];
	for(int j=0;j<=n-1;j++)
		temp[j]=vec[n-1][j];
	for(int i=n-2;i>0;i--)
		for(int j=0;j<=i;j++)
			temp[j]=max(temp[j],temp[j+1])+vec[i][j];
	return vec[0][0]+max(temp[0],temp[1]);
}

int main()
{
	vec[0][0]=7;
	vec[1][0]=3,vec[1][1]=8;
	vec[2][0]=8,vec[2][1]=1;vec[2][2]=0;
	vec[3][0]=2,vec[3][1]=7,vec[3][2]=4,vec[3][3]=4;
	vec[4][0]=4,vec[4][1]=5,vec[4][2]=2,vec[4][3]=6,vec[4][4]=5;

	cout<<DiTui(vec,5)<<endl;
	cout<<DiTui(vec,5)<<endl;
}

  

时间: 2024-10-07 11:48:04

三角形问题——(递归,递推,动态规划)的相关文章

再谈循环&amp;迭代&amp;回溯&amp;递归&amp;递推这些基本概念

循环:不断重复进行某一运算.操作. 迭代:不断对前一旧值运算得到新值直到达到精度.一般用于得到近似目标值,反复循环同一运算式(函数),并且总是把前一 次运算结果反代会运算式进行下一次运算 递推:从初值出发反复进行某一运算得到所需结果.-----从已知到未知,从小到达(比如每年长高9cm,20年180,30后270) 回溯:递归时经历的一个过程. 递归:从所需结果出发不断回溯前一运算直到回到初值再递推得到所需结果----从未知到已知,从大到小,再从小到大(你想进bat,那么编程就的牛逼,就得卸载玩

递归--递推之组合数

排列在上一篇中已经写到,是个典型的深搜题,下面是介绍的组合数, 组合的基本定义是, 但是除了用这种传统的方法来求,可以用递归的方式或者是递推的方式来求, 说道递推,只要会递归, 就会递推了.关键的一部是递推式,可以定义一个函数func(int n, int k); 表示求的值,公式先放在这func(n, k) = func(n-1, k-1)+func(n-1,k); 意思就是在n中选去k个数的组合一个多少个,这时就要分两种情况, 一种是选出一组数中包含最后一个元素,它的值就是func(n -

POJ-1163-The Triangle: DP入门 递归 递推

递归思路 超时算法 #include<iostream> using namespace std; #define Size 101 int Triangle[Size][Size]; int n; int GetAns( int i, int j ) { if( i==n ) return Triangle[i][j]; int x=GetAns( i+1, j ); int y=GetAns( i+1, j+1 ); return max(x, y)+Triangle[i][j]; } i

【Java】课后动手动脑及递归递推的应用

1.代码 表示方法为静态方法,在其它类中可以直接通过类名去调用这个方法! 例如public static void main(String[] args){ClassName.prt("abc");}如果不加static,则只有通过该类的对象去调用.例如public static void main(String[] args){ClassName name=new ClassName();name.prt("abc");} 2.线性同余纯随机数生成器 3.代码 4

函数递归 - 递推与回溯 练习题

递归与二分法习题二分法就是在按照从大到小或者从小到大规律排布的列表中,寻找的值通过与中间的值比较大小,从而对列表进行操作,然后再比较的循环过程. 用递归的方法找出列表中的值num = [1,3,4,5,6,8,22,33,55,778,990]def search(search_number,num): if len(num) == 0:return mid = len(num) // 2 mid_nums = num[len(num)//2] if search_number > mid_nu

斐波那契数列数组递归递推的时间空间复杂度的分析

3g0gpapcgj傅节涤澳浩日换崭睹速<http://weibo.com/p/230927987595257304584192> nfdc5g6tss谅渍狙庇淤律臼忠圆账<http://weibo.com/p/230927987596255930617856> 2kvbhyaba6棠妨睦阶月忧杜懊猎茄<http://weibo.com/p/230927987595884084596736> iw27choola戮鸵垦呀粟傧段厍刀推<http://weibo.co

Prob.2[动态规划+递推+划归思想的应用]POJ 1958 Strange Towers Of Hanoi Upd:2020.3.1

传送门:http://poj.org/problem?id=1958 汉诺塔:https://www.cnblogs.com/antineutrino/p/3334540.html 问题引入:这个在标准的三塔问题上又加了一维,我们先考虑三个塔是怎么计算的?可以具体地分成三个步骤: 1.假设A塔上有n个盘子,将A塔上n-1个盘子转移到B塔上. 2.将A塔上剩余的一个盘子转移到C塔上. 3.将B塔上剩余的n-1个盘子转移到C塔上 因为后转移的盘子小,上面n-1个盘子都能落在上面,2之后的C柱可以看成

算法--递推策略

本文地址:http://www.cnblogs.com/archimedes/p/4265019.html,转载请注明源地址. 递推法是一种重要的数学方法,在数学的各个领域中都有广泛的运用,也是计算机用于数值计算的一个重要算法.这种算法特点是:一个问题的求解需一系列的计算,在已知条件和所求问题之间总存在着某种相互联系的关系,在计算时,如果可以找到前后过程之间的数量关系(即递推式),那么,从问题出发逐步推到已知条件,此种方法叫逆推.无论顺推还是逆推,其关键是要找到递推式.这种处理问题的方法能使复杂

动态规划 数字三角形(递归,递推,记忆化搜索)

题目要求: 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 在上面的数字三角形中寻找在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大.路径上的每一步都只能往左下或右下走.只需要求出这个最大和即可,不必给出具体路径. 三角形的行数大于1小于等于100,数字为 0 - 99 输入格式: 5 //三角形行数.下面是三角形 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 解题思路: 用二维数组存放数字三角形 D[r][j] //表示第i行第j个元素的

动态规划&mdash;&mdash;数字三角形(递归or递推or记忆化搜索)

动态规划的核心就是状态和状态转移方程. 对于该题,需要用抽象的方法思考,把当前的位置(i,j)看成一个状态,然后定义状态的指标函数d(i,j)为从格子出发时能得到的最大和(包括格子本身的值). 在这个状态定义下,原问题的解就是d(i,j). 下面看一下不同状态之间如何转移.从格子(i,j)出发有两种策略.如果向左走,则到(i+1,j)后需要求"从(i+1,j)出发能得到的最大和"这一问题,即d(i+1,j). 类似的,往右走之后需要求解d(i+1,j+1).由于可以在这两个决策中自由选