用java解决数字三角形问题(动态规划)

问题描述:试设计一个算法,计算出从三角形的顶到底的一条路径,使该路径经过的数字总和最大,输出最大值和具体路径。

算法构思:采用动态规划的方法自底向上求解较大值,并将每次求的的值保存到一个二维数组中,该数组的行数比原用来记录数字三角形的二维数组的行数少一行,通过该数组可以避免重复计算,且最大值为该数组的第一行第一列元素。另用一个二维数组记录路径,并根据该数组自顶向下找到获得最大值的路径并输出。

代码实现:

package shzsjx;
import java.util.Scanner;
public class shzsjx 
{
	public static int Max_(int a,int b)//求二者中较大值
	{
		int max=0;
		if(a>=b)
			max=a;
		else
			max=b;
		return max;
	}
	public static void main(String[] args)
	{
		System.out.print("请输入数字三角形的行数: ");
		Scanner scanner = new Scanner(System.in);
		int n=scanner.nextInt();
		int a[][] = new int[n][n];//用来存储原数字三角形的值
		for(int i=0;i<n;i++)//为三角形赋初值
		{
			for(int j=0;j<=i;j++)
			{
				a[i][j]=scanner.nextInt();
			}
		}
		int [][]b = new int[n-1][n-1];//采用动态规划时,用来记录新数据
		int [][]c = new int[n-1][n-1];//用来记录路径,0向下,1向右下
		for(int i=n-2;i>=0;i--)
		{
			for(int j=0;j<=i;j++)
			{
				if(i==n-2)
				{
					b[i][j]=a[i][j]+Max_(a[i+1][j],a[i+1][j+1]);//填写新三角形的最后一行
				}
				else
				{
					b[i][j]=a[i][j]+Max_(b[i+1][j],b[i+1][j+1]);//填写新三角形的其余行
				}
				if(a[i+1][j]==a[i+1][j+1] && i<n-2)//若向下走和向右走值一样,就向下试探一步再确定
				{
					if(b[i+1][j]>b[i+1][j+1])//向下走值大
						c[i][j]=0;//向下
					else if(b[i+1][j]<b[i+1][j+1])//向右下走值大
						c[i][j]=1;//向右下
				}
				else if(a[i+1][j]!=a[i+1][j+1])
				{
				    if(Max_(a[i+1][j],a[i+1][j+1])==a[i+1][j])//记录原数字三角形向下走值较大的路径,0向下,1向右下(该行的下一行如何走)
					    c[i][j]=0;//向下
				    else if(Max_(a[i+1][j],a[i+1][j+1])==a[i+1][j+1])
					    c[i][j]=1;//向右下	
				}
			}
		}
		System.out.println("中间过程产生的新三角形为:");
		for(int i=0;i<=n-2;i++)
		{
			for(int j=0;j<=i;j++)
			{
				System.out.print(b[i][j]+" ");
			}
			System.out.println();
		}
		System.out.println("从原数字三角形中可以得到最大值为: "+b[0][0]);
		System.out.println("具体路径如下:");
		System.out.print(a[0][0]+"->");
		int j=0;
		for(int i=0;i<=n-2;)//根据数组c记录的路径,找到一条值最大的路径
		{
			if(c[i][j]==0)
			{
				System.out.print(a[i+1][j]);
				i++;
			}
			else if(c[i][j]==1)
			{
				System.out.print(a[i+1][j+1]);
				i++;
				j++;
			}
			if(i<=n-2)
				System.out.print("->");
		}
	}
}

运行结果:

 注意:在选择第三行的6的下一个元素时,由于向下走和向右下走值一样,所以采用向下试探的方法来确定具体路径,在这里看16和17,由于17大于16,所以6向右下走,而不向下走。

此次分享到此结束,如有问题请多多指教!

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值