dp专题训练:数字三角形(打印路径)

该题也没有要求我们打印出最大三角形的路径,在此我们做一定的拓展!

方案同求最长上升子序列,定义一个结构体,该结构体包含三个数值,一为最大的路径大小,以及轨迹中上一点的x坐标和y坐标。最初的点坐标定义为(-1,-1).运用递归的结构打印,当遇到坐标点为(-1,-1)时返回走向上一层。

描述

        7
      3   8
    8   1   0
  2   7   4   4
4   5   2   6   5

      (图1)


图1给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。

注意:路径上的每一步只能从一个数走到下一层上和它最近的左边的那个数或者右边的那个数。

输入

输入的是一行是一个整数N (1 < N <= 100),给出三角形的行数。下面的N行给出数字三角形。数字三角形上的数的范围都在0和100之间。

输出

输出最大的和。

样例输入

5
7
3 8
8 1 0 
2 7 4 4
4 5 2 6 5

样例输出

30
#include<stdio.h>
struct triangle{
	int maxval;
	int prex;                  //记录上一个点的坐标x。 
	int prey;                  //记录上一个点的坐标y。 
}dp[101][101];
int trival[101][101];          //记录三角形的值。 
int max(int a,int b)
{
	return a>b?a:b;
}
void print(int a,int b)        //运用递归打印出最大三角形的轨迹 。 
{
	if(dp[a][b].prex==-1&&dp[a][b].prey==-1)
	{
		printf("%d ",trival[a][b]);
		return;
	}
	else
	{
		print(dp[a][b].prex,dp[a][b].prey);
		printf("%d ",trival[a][b]);
	}
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
		{
			scanf("%d",&trival[i][j]);
		}
	}
	for(int i=1;i<=n;i++)
	{
		dp[n][i].maxval=trival[n][i];
		dp[n][i].prex=-1;
		dp[n][i].prey=-1;
	}
	for(int i=n-1;i>=1;i--)
	{
		for(int j=1;j<=i;j++)
		{
			if(dp[i+1][j].maxval>dp[i+1][j+1].maxval)
			{
				dp[i][j].maxval=dp[i+1][j].maxval+trival[i][j];
				dp[i][j].prex=i+1;                      //记录轨迹中上一个点的x坐标 。 
				dp[i][j].prey=j;                        //记录轨迹中上一个点的y坐标 。 
			}
			else
			{
				dp[i][j].maxval=dp[i+1][j+1].maxval+trival[i][j];
				dp[i][j].prex=i+1;
				dp[i][j].prey=j+1;
			}
			
		}
	}
	printf("%d\n",dp[1][1].maxval);
	print(1,1);
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/mavises/article/details/81410844
今日推荐