XYNUOJ 1454 数字三角形(递归和递推两种方法)

1454: 数字三角形

时间限制: 1 Sec   内存限制: 128 MB
提交: 15   解决: 8
您该题的状态:已完成
[提交][状态][讨论版]

题目描述

数字三角形,从三角形顶部往下走,只能往左下或右下走,求走到最下面时所经过的数字和最大为多少?(下图为n=6时的情况)


          2          
        96   30        
      83   52   60      
    21   65   44   61    
  8   79   50   41   21  
61   41   50   38   79   10

输入

第1行:整数n(1<=n<=1000)

第2-n+1行:每行若干整数,第i行有i-1个整数空格分隔。

输出

一行:一个整数,表示所经过数字的最大和。

样例输入

6					
2					
96	30				
83	52	60			
21	65	44	61		
8	79	50	41	21	
61	41	50	38	79	10

样例输出

375

AC代码:

递归算法:

#include 
#include 
#include 
using namespace std;
int n;
int a[1005][1005];
int dp[1005][1005];//dp[i][j]表示从点(i,j)出发能走过的最大和 
int getdp(int i,int j)//计算dp[i][j] 
{
	if(dp[i][j]!=-1) return dp[i][j];//如果已经处理过就直接返回值,剪枝
    return dp[i][j]=a[i][j]+(i==n?0:max(getdp(i+1,j),getdp(i+1,j+1))); //i=n时就到最后一层了,递归开始回溯 
}
int main()
{
  scanf("%d",&n);
  for(int i=1;i<=n;i++)
  for(int j=1;j<=i;j++)
  scanf("%d",&a[i][j]),dp[i][j]=-1;//赋初值-1的目的:getdp(i,j)的时候通过看dp[i][j]是否不等于-1可得知它是否被处理过,剪枝 
  printf("%d\n",getdp(1,1));//最终求从点(1,1)出发到最后一层经过的最大和 
  return 0;
}

递推算法(逆序枚举):

#include 
#include 
#include 
using namespace std;
int n;
int a[1005][1005];
int dp[1005][1005];//dp[i][j]表示从点(i,j)出发能走过的最大和 
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=i;j++)
	scanf("%d",&a[i][j]),dp[i][j]=0,dp[n][j]=a[n][j];//初始最大值都是0,最后一行最大值是自身 
	for(int i=n-1;i>=1;i--)//从倒数第二行第一个数开始赋值 
	for(int j=1;j<=i;j++)
	dp[i][j]=a[i][j]+max(dp[i+1][j],dp[i+1][j+1]);
	printf("%d\n",dp[1][1]);//最终求从点(1,1)出发到最后一层经过的最大和 
	return 0;
}

你可能感兴趣的:(XYNUOJ 1454 数字三角形(递归和递推两种方法))