题目一:数问塔题

import java.util.Scanner;

public class testMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a[][][] = new int[50][50][50];
		int i, j;
		int n = 5;
		Scanner scanner = new Scanner(System.in);
		for (i = 1; i <= n; i++) {
			for (j = 1; j <= i; j++) {
				a[i][j][1] = scanner.nextInt();
				a[i][j][2] = a[i][j][1];
				a[i][j][3] = 0;
			}
		}for (i = 1; i <= n; i++) {
			for (j = 1; j <= i; j++) {
				System.out.print(a[i][j][1]);
				
			}
			System.out.println();
		}
		for (i = n - 1; i >= 1; i--)
			for (j = 1; j <= i; j++)
				if (a[i + 1][j][2] > a[i + 1][j + 1][2]) {
					a[i][j][2] = a[i][j][2] + a[i + 1][j][2];
					a[i][j][3] = 0;
				} else {
					a[i][j][2] = a[i][j][2] + a[i + 1][j + 1][2];
					a[i][j][3] = 1;
				}
		System.out.println("max="+a[1][1][2]);
		j=1;
		for( i=1 ;i<= n-1;i++)
		 {  System.out.println(a[i][j][1]+"->");
		 	j=j+a[i][j][3]; }
		System.out.println (a[n][j][1]);
	}
}

给定一个数塔,其存储形式为如下所示的下三角矩阵。在此数塔中,从顶部出发,在每一节点可以选择向下走还是向右走,一直走到底层。请找出一条路径,使路径上的数值和最大。

输入样例(数塔):

9

12    15

10   6    8

2    18  9    5

19   7   10   4    16

输出样例(最大路径和):

59


 算法设计

 动态规划设计过程如下:

 1.阶段划分:

  第一步对于第五层的数据,我们做如下五次决策:

       对经过第四层2的路径选择第五层的19,

       对经过第四层18的路径选择第五层的10,

       对经过第四层9的路径也选择第五层的10,

       对经过第四层5的路径选择第五层的16。

        以上的决策结果将五阶数塔问题变为4阶子问题,递推

出第四层与第五层的和为:

       21(2+19),28(18+10),19(9+10),21(5+16)。

    用同样的方法还可以将4阶数塔问题,变为3阶数塔问题。

……最后得到的1阶数塔问题,就是整个问题的最优解。

 2.存储、求解:

     1) 原始信息存储

        原始信息有层数和数塔中的数据,层数用一个整型

     变量n存储,数塔中的数据用二维数组data,存储成如

     下的下三角阵:

              9

             12    15

             10     6     8

              2    18     9    5

             19     7    10    4   16

 2)动态规划过程存储

    必需用二维数组a存储各阶段的决策结果。二维数组a的存储内容如下:

    d[n][j]=data[n][j]         j=1,2,……,n;

    i=n-1,n-2,……1,j=1,2,……,i;时

    d[i][j]=max(d[i+1][j],d[i+1][j+1])+data[i][j]

    最后a[1][1]存储的就是问题的结果。

3)最优解路径求解及存储

    仅有数组data和数组a可以找到最优解的路径,但需要自顶向下比较数组data和数组a是可以找到。如图4.5.2求解和输出过程如下:

 输出a[1][1]"9"

  b=d[1][1]-data[1][1]=59-9=50  b与d[2][1],d[2][2]比较

 b与d[2][1]相等输出data[2][1]"12"

  b=d[2][1]-data[2][1]=50-12=38  b与d[3][1],d[3][2]比较

 b与d[3][1]相等输出data[3][1]"10"

  b=a[3][1]-data[3][1]=38-10=28    b与d[4][1],d[4][2]比较

 b与d[4][2]相等输出data[4][2]"18"

  b=d[4][2]-data[4][2]=28-18=10  b与d[5][2],d[5][3]比较

 b与d[5][3]相等输出data[5][3]"10“

                     

                 数组data    

    12 15                    50  49

    10 6   8                 38  34  29

    2  18  9   5            21  28  19  21

    19 7   10  4 16         19  7  10  4   16

             图4-12 数塔及动态规划过程数据

                    为了设计简洁的算法,我们最后用三维数组a[50][50][3]存储以上确定的三个数组的信息。 

            a[50][50][1]代替数组data,

            a[50][50][2]代替数组d,

            a[50][50][3]记录解路径。

                                 数组d

    9                         59

    12 15                    50  49

    10 6   8                 38  34  29

    2  18  9   5            21  28  19  21

    19 7   10  4 16         19  7  10  4   16

             图4-12 数塔及动态规划过程数据

                    为了设计简洁的算法,我们最后用三维数组a[50][50][3]存储以上确定的三个数组的信息。 

            a[50][50][1]代替数组data,

            a[50][50][2]代替数组d,

            a[50][50][3]记录解路径。

                   


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值