动态规划-数字三角形问题(java实现)

数字三角形问题

给定一个由 n 行数字组成的数字三角形,试设计一个算法,计算出 从三角形的顶至底的一条路径,使该路径经过的数字总和最大。
试写出递归算法,再利用实验中的思路把它转化为备忘录法和动态规划算法
在这里插入图片描述

1:递归算法

public class DynamicProgramming {

//    三角形行数
    private int n = 5;
//    三角形数据
    private int[][] nums = {
            { 9},
            {12,  15},
            {10,   6,   8},
            { 2,  18,   9,   5},
            {19,   7,  10,   4,  16},
    };
//    递归算法
    public int test(int x,int y) {
    //如果已经到三角形底部就直接返回底部的数据
        if(x == n-1) {
            return nums[x][y];
        }
    //每个位置下面有两个选择,选择最大和的那个
        return (nums[x][y] + (test(x+1,y) >= test(x+1,y+1) ? test(x+1,y) : test(x+1,y+1)));
    }
    public static void main(String[] args) {
        DynamicProgramming dynamicProgramming = new DynamicProgramming();
        System.out.println(dynamicProgramming.test(0,0));
    }
}

2:带备忘录的递归算法

public class DynamicProgramming {

//    三角形行数
    private int n = 5;
//    三角形数据
    private int[][] nums = {
            { 9},
            {12,  15},
            {10,   6,   8},
            { 2,  18,   9,   5},
            {19,   7,  10,   4,  16},
    };
//    备忘录
    int[][] table = new int[n][n];

/*
* 描述:用于计算三角形数据的最大和
* 参数:三角形数据二维数组的坐标x和y
* 返回值:三角形数据的最大和
* */
    public int test(int x,int y) {
        //如果已经到三角形底部就直接返回底部的数据
        if(x == n-1) {
            return nums[x][y];
        }
        //如果备忘录里面有值,直接返回备忘录数组中的值
        if(table[x][y] != 0) {
            return table[x][y];
        }
        //每个位置下面有两个选择,选择最大和的那个,当前位置的三角形数据与最大和的那个相加
        return table[x][y] = (nums[x][y] + (test(x+1,y) >= test(x+1,y+1) ? test(x+1,y) : test(x+1,y+1)));
    }

    public static void main(String[] args) {
        DynamicProgramming dynamicProgramming = new DynamicProgramming();
        System.out.println(dynamicProgramming.test(0,0));
    }
}


3:动态规划法

public class DynamicProgramming {

    //    三角形行数
    private int n = 5;
    //    三角形数据
    private int[][] nums = {
            { 9},
            {12,  15},
            {10,   6,   8},
            { 2,  18,   9,   5},
            {19,   7,  10,   4,  16},
    };
//    //    备忘录
//    int[][] table = new int[n][n];
//
//    /*
//    * 描述:用于计算三角形数据的最大和
//    * 参数:三角形数据二维数组的坐标x和y
//    * 返回值:三角形数据的最大和
//    * */
//    public int test(int x,int y) {
//        //如果已经到三角形底部就直接返回底部的数据
//        if(x == n-1) {
//            return nums[x][y];
//        }
//        //如果备忘录里面有值,直接返回备忘录数组中的值
//        if(table[x][y] != 0) {
//            return table[x][y];
//        }
//        //每个位置下面有两个选择,选择最大和的那个,当前位置的三角形数据与最大和的那个相加
//        return table[x][y] = (nums[x][y] + (test(x+1,y) >= test(x+1,y+1) ? test(x+1,y) : test(x+1,y+1)));
//    }

    /*
     * 描述:用于计算三角形数据的最大和
     * 参数:三角形数据二维数组的坐标x和y
     * 返回值:三角形数据的最大和
     * */
    public int test1() {
        //  对nums二维数组的行作遍历,从倒数第二行开始
        int start = n-2;
        for(int i = start; i >= 0; i--) {
            //  每一行的长度
            int j = nums[i].length;
            //  对nums二维数组的行中的数组元素作遍历
            for(int k = 0; k < j; k++) {
                nums[i][k] += (nums[i+1][k] >= nums[i+1][k+1] ? nums[i+1][k] : nums[i+1][k+1]);
            }
        }
        //  返回三角形顶的数据,此时的三角形顶的值就是三角形最大和
        return nums[0][0];
    }

    public static void main(String[] args) {
        DynamicProgramming dynamicProgramming = new DynamicProgramming();
//        System.out.println(dynamicProgramming.test(0,0));
        System.out.println(dynamicProgramming.test1());

    }
}

在这个实验中,我了解到了动态规划的基本思想,即聪明的枚举,尽量让以前走过的步骤不白走,在以后的步骤中能用上以前计算过的数据,做到不重复计算,实验分为三步,第一步就是平常的递归算法,第二步就是不做重复计算的递归算法,第三步是节省了空间的非递归算法(自底向上寻求答案)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值