礼物的最大值

题目:在一个m×n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值
(价值大于0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向左或
者向下移动一格直到到达棋盘的右下角。给定一个棋盘及其上面的礼物,请计
算你最多能拿到多少价值的礼物?

动态规划:定义f(i,j)为到达(i,j)位置格子时能拿到的礼物总和的最大值,则有:f(i,j)=max{f(i,j),f(i,j)}+values(i,j)。 同上道题一样,如果直接使用递归会产生大量的重复计算,因此,创建辅助的数组来保存中间计算结果。
辅助数组不用和m*n的二维数组一样大,只需要保存上一层的最大值就可以。代码中使用长度为列数n的一位数组作为辅助数组,
注释部分为二维辅助数组。
1.动态规划问题,用公式来表示清楚。
2.动态规划如果有大量重复计算,可以用循环+辅助空间来提高效率。
3.这道题不用二维数组,只需要用一维数组作为辅助空间即可,以后遇到对中间结果的保存问题,看看能否优化辅助空间。

可以用一维数组代替二维数组,但我没有。

package helen.b;

public class MaxValueOfGift {

//    { 1, 2, 3 },
//    { 4, 5, 6 },
//    { 7, 8, 9 }
    private int maxValueOfGifts(int[][] values) {
        if (values == null) {
            return 0;
        }
        int giftValue[][] = new int[values.length][values[0].length];
        giftValue[0][0]=values[0][0];
        for(int i=0;i<values.length;i++){
            for(int j=0;j<values[0].length;j++){
                int up=0;
                int left=0;
                if(i>0) {
                    up = giftValue[i - 1][j];
                }
                if(j>0){
                    left=giftValue[i][j-1];
                }
                giftValue[i][j]=values[i][j]+Math.max(up,left);

            }
        }

        return giftValue[values.length-1][values[0].length-1];
    }



    void test(String testName, int[][] values, int rows, int cols, int expected){
        if(maxValueOfGifts(values) == expected)
            System.out.println(testName+" solution1 passed");
        else
            System.out.println(testName+" solution1 FAILED");
    }


    void test1(){
        // 三行三列
        int values[][] = {
                { 1, 2},
                { 4, 5}
        };
        int expected = 10;
        test("test1",values, 2, 2, expected);
    }

    void test2(){
        //四行四列
        int values[][] = {
                { 1, 10, 3, 8 },
                { 12, 2, 9, 6 },
                { 5, 7, 4, 11 },
                { 3, 7, 16, 5 }
        };
        int expected = 53;
        test("test2", values, 4, 4, expected);
    }

    void test3(){
        // 一行四列
        int values[][] = {
                { 1, 10, 3, 8 }
        };
        int expected = 22;
        test("test3",  values, 1, 4, expected);
    }

    void test4(){
        int values[][] = {
                { 1 },
                { 12 },
                { 5 },
                { 3 }
        };
        int expected = 21;
        test("test4",  values, 4, 1, expected);
    }

    void test5(){
        // 一行一列
        int values[][] = {
                { 3 }
        };
        int expected = 3;
        test("test5", values, 1, 1, expected);
    }

    void test6(){
        // 空指针
        int expected = 0;
        test("test6", null, 0, 0, expected);
    }

    public static void  main( String  arg[]){

         new MaxValueOfGift().test1();
        new MaxValueOfGift().test2();
        new MaxValueOfGift().test3();
        new MaxValueOfGift().test4();
        new MaxValueOfGift().test5();
        new MaxValueOfGift().test6();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值