• 动态规划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];

     

  • 相关阅读:
    NetworkInterface网速监测
    动态编译
    JSON C# Class Generator
    Cookie中的HttpOnly
    webapi session
    没有为扩展名“.html”注册的生成提供程序
    转 C# 使用openssl
    openssl jia adress
    扩展JS
    bootstrap 模态
  • 原文地址:https://www.cnblogs.com/weizhibin1996/p/9255653.html
Copyright © 2020-2023  润新知