动态规划2

大量的重复子问题

 

 通过解决n-1,n-2,n-3 ······· 1等子问题就能解决原问题。

 

 

 如果一个题目,能够通过解决自问题就能找到答案,那么就能动态规划!

 

 

递归写法

记忆化搜索

动态规划写法

但是还是平方级别的

 

我的代码

其实就是比较j*(i-j)和j*memo【i-j】

因为分解出来是对称的,前面已经计算过1*xxx了后面就不用计算xxx*1了,刚好1不需要遍历

private int memo[];

    public int integerBreak(int n) {

        memo = new int[n+1];

        //基础问题 1 的值对应什么? 1 还是不要遍历了,memo【1】没法填。。。
        memo[2]=1;

        //对于3-n的每个值,填memo数组,对应的是该值的解
        for(int i=3;i<=n;i++){

            int max = 0;


            //因为不遍历1,所以j要到i-1之前就停止
            for(int j=1;j<i-1;j++){

                //计算j*(i-j)
                int temp1 = j*(i-j);
                int temp2 = j*memo[i-j];

                //因为memo【n】不一定比n大,比如2和3
                //memo【n】是n分割乘积的最大值,也就是别的组合里面最大值
                int tempMax = temp1;
                if(temp2>tempMax)
                    tempMax=temp2;

                if(tempMax>max)
                    max=tempMax;

            }

            memo[i]=max;

        }

        return memo[n];

 

舒服

 

 

一次通过美滋滋

 

 

279

91

62

和64号问题很像,也是一个数组从【m】【n】回填到【0】【0】即可

基本是简化版的64,因为最后和最右都是1.

public int uniquePaths(int m, int n) {
        int [][] matrix = new int[m][n];

        //从最后一个开始,最后一行,最后一烈,这样逆序,一直到【0】【0】
        for(int i=m-1;i>=0;i--){

            for(int j=n-1;j>=0;j--){

                if(i==m-1&&j==n-1){
                    matrix[i][j]=1;
                }else if(i==m-1){
                    //最后一行,无论如何都是只有一种走法,就是往右走
                    matrix[i][j]=1;
                }else if(j==n-1){
                    //最右列也只有一直往下走
                    matrix[i][j]=1;
                }else{

                    //其他就是右边的方法数加上右边的方法数
                    int right = matrix[i][j+1];
                    int next = matrix[i+1][j];
                    matrix[i][j]=right+next;

                }

            }

        }

        return matrix[0][0];
    }

 

 一次嘻嘻

 

63

 

这个其实也不是难了很多

先遍历,将1变成-1,障碍都用-1表示。

依旧是以前那样,从后面填。

如果右边或下边是-1的,就将这边的路径当作0就好了。

这个题目我没有一次过,主要是漏了几个情况。

1、开始或终点就是障碍物,这种直接返回0,就是无法到达。

2、如果最后一行的右边不是-1,那么就设为1。错了啊,右边还可能是0呢。

3、忘了判断这个数本身是不是-1.

最后修改的代码,不是很优雅,但是思路能看清。

        //如果开始就是1,直接就不可能了
        if(obstacleGrid[0][0]==1)
            return 0;


        //
        int row = obstacleGrid.length;

        //
        int col = obstacleGrid[0].length;

        //如果终点是1,也是不可能的
        if(obstacleGrid[row-1][col-1]==1)
            return 0;


        for(int i=0;i<row;i++){

            for(int j=0;j<col;j++){

                if(obstacleGrid[i][j]==1)
                    obstacleGrid[i][j]=-1;

            }

        }


        //从后面设置起
        for(int i=row-1;i>=0;i--){

            for (int j=col-1;j>=0;j--){

                if(i==row-1&&j==col-1){
                    obstacleGrid[i][j]=1;
                }else if(i==row-1){

                    //看自己是不是-1
                    if(obstacleGrid[i][j]==-1)
                        continue;

                    //最后一行,要看右边是不是-1
                    if(obstacleGrid[i][j+1]==-1)
                        obstacleGrid[i][j]=0;
                    else
                        //右边有可能是0
                        obstacleGrid[i][j]=obstacleGrid[i][j+1];

                }else if(j==col-1){

                    //看自己是不是-1
                    if(obstacleGrid[i][j]==-1)
                        continue;

                    //最右一列,看看下边是不是-1
                    if(obstacleGrid[i+1][j]==-1)
                        obstacleGrid[i][j]=0;
                    else
                        //下边有可能是0
                        obstacleGrid[i][j]=obstacleGrid[i+1][j];

                }else{

                    if(obstacleGrid[i][j]==-1)
                        continue;
                    else{

                        int right = obstacleGrid[i][j+1];
                        int next = obstacleGrid[i+1][j];

                        if(right!=-1)
                            obstacleGrid[i][j]+=right;
                        if(next!=-1)
                            obstacleGrid[i][j]+=next;

                    }

                }

            }

        }


        return obstacleGrid[0][0];

 

 

posted @ 2018-07-02 20:38  朋友圈  阅读(150)  评论(0编辑  收藏  举报