动态规划2

Posted lizzyluvcoding

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划2相关的知识,希望对你有一定的参考价值。

坐标型

115. Unique Paths II

https://www.lintcode.com/problem/unique-paths-ii/description?_from=ladder&&fromId=16

技术图片
public class Solution {
    /**
     * @param obstacleGrid: A list of lists of integers
     * @return: An integer
     */
    private static int OBSTACLE = 1;
    private static int BLANK = 0;
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        // write your code here
        if(obstacleGrid==null || obstacleGrid.length==0 || obstacleGrid[0].length==0){
            return 0;
        }
        
        int m = obstacleGrid.length;
        int n = obstacleGrid[0].length;
        int[][] f = new int[m][n];
        
        
        for(int i=0;i<m;i++){
            if(obstacleGrid[i][0]==OBSTACLE){
                break;
            }
            
            f[i][0] = 1;
        }
        
        for(int j=0;j<n;j++){
            if(obstacleGrid[0][j]==OBSTACLE){
                break;
            }
            
            f[0][j]=1;
        }
        
        for(int i=1;i<m;i++)
            for(int j=1;j<n;j++){
                if(obstacleGrid[i][j]==OBSTACLE){
                    continue;
                }
                f[i][j]=f[i-1][j]+f[i][j-1];
            }
            
        return f[m-1][n-1];
    }
}
View Code

 

序列型:前i 个 最小/方式数/可行性

515. Paint House

思路:通过二维数组记录状态,f[i][j]表示前i栋房子(最后一栋是i-1)且i-1栋分别为j号颜色的最小花费

https://www.lintcode.com/problem/paint-house/description?_from=ladder&&fromId=16

技术图片
public class Solution {
    /**
     * @param costs: n x 3 cost matrix
     * @return: An integer, the minimum cost to paint all houses
     */
    public int minCost(int[][] costs) {
        // write your code here
        if(costs==null || costs.length ==0 || costs[0].length==0){
            return 0;
        }
        
        int r = costs.length;  //房子的个数
        int c = costs[0].length; //颜色的个数
        
        int[][] f = new int [r+1][c];  //注意需要r+1个状态
        
        f[0][0]=f[0][1]=f[0][2]=0;
        
        for(int i =1;i<=r;i++){
            for(int j=0;j<3;j++){
                f[i][j] = Integer.MAX_VALUE;
                
                for(int k=0;k<3;k++){
                    if(j!=k){
                        f[i][j] = Math.min(f[i][j],f[i-1][k]+costs[i-1][j]);
                    }
                }
            }
        }
        
        return Math.min(f[r][0],Math.min(f[r][1],f[r][2]));
    }
}
View Code

 

划分型:

512. Decode Ways

思路:前i个字符有f[i]种解密方式

边界情况:i=1,只看一个数字 即f[0]=1

https://www.lintcode.com/problem/decode-ways/description?_from=ladder&&fromId=16

技术图片
public class Solution {
    /**
     * @param s: a string,  encoded message
     * @return: an integer, the number of ways decoding
     */
    public int numDecodings(String ss) {
        // write your code here
        char[] s = ss.toCharArray();
        int n = s.length;
        if(n==0){
            return 0;
        }
        
        int[] f = new int[n+1];
        f[0] = 1;
        
        for(int i =1;i<=n;i++){
            f[i]=0;
            //last digit represent a letter
            if(s[i-1]!=‘0‘){
                f[i]+=f[i-1];
            }
            
            //last two represent a letter
            if(i>=2 &&(s[i-2]==‘1‘ || (s[i-2]==‘2‘ && s[i-1]<=‘6‘))){
                f[i]+=f[i-2];
            }
        }
        
        return f[n];
    }
}
View Code

 

滚动数组优化空间:

110. Minimum Path Sum

https://www.lintcode.com/problem/minimum-path-sum/description?_from=ladder&&fromId=16

技术图片
public class Solution {
    /**
     * @param grid: a list of lists of integers
     * @return: An integer, minimizes the sum of all numbers along its path
     */
    public int minPathSum(int[][] A) {
        // write your code here
        if(A==null || A.length==0|| A[0].length==0){
            return 0;
        }
        int m = A.length;
        int n = A[0].length;
        int[][]f = new int[2][n];
        int i,j;
        int old=0;   //i-1行结果
        int now =1; //当前处理的第i行存在now
        
        for(i=0;i<m;i++){
            old = now;
            now = 1-now;
            
            for(j=0;j<n;j++){
                if(i==0&& j==0){
                    f[now][0] = A[0][0];
                    continue;
                }
                
                f[now][j] = Integer.MAX_VALUE;
                
                if(i>0){
                    f[now][j] = Math.min(f[now][j],f[old][j]+A[i][j]);
                }
                
                if(j>0){
                    f[now][j] = Math.min(f[now][j],f[now][j-1]+A[i][j]);
                }
            }
        }
        
        return f[now][n-1];
    }
}
View Code

 

坐标型动态规划:

553. Bomb Enemy

https://www.lintcode.com/problem/bomb-enemy/description?_from=ladder&&fromId=16

技术图片
public class Solution {
    /**
     * @param grid: Given a 2D grid, each cell is either ‘W‘, ‘E‘ or ‘0‘
     * @return: an integer, the maximum enemies you can kill using one bomb
     */
    private static char ENEMY = ‘E‘;
    private static char WALL = ‘W‘;
    private static char BLANK = ‘0‘;
    public int maxKilledEnemies(char[][] grid) {
        // write your code here
        if(grid==null || grid.length==0 || grid[0].length==0){
            return 0;
        }
        
        int m = grid.length;
        int n = grid[0].length;
        
        int[][] UP = new int[m][n];
        int[][] DOWN = new int[m][n];
        int[][] LEFT = new int[m][n];
        int[][] RIGHT = new int[m][n];
        
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                UP[i][j]=0;
                if(grid[i][j]==WALL){
                    continue;
                }
                
                if(grid[i][j]==ENEMY){
                    UP[i][j]=1;
                }
                
                if(i>0){
                    UP[i][j]+=UP[i-1][j];
                }
            }
        }
        
        for(int i=m-1;i>=0;i--){
            for(int j=0;j<n;j++){
                DOWN[i][j]=0;
                if(grid[i][j]==WALL){
                    continue;
                }
                
                if(grid[i][j]==ENEMY){
                    DOWN[i][j]=1;
                }
                
                if(i+1<m){
                    DOWN[i][j]+=DOWN[i+1][j];
                }
            }
        }
        
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                LEFT[i][j]=0;
                if(grid[i][j]==WALL){
                    continue;
                }
                
                if(grid[i][j]==ENEMY){
                    LEFT[i][j]=1;
                }
                
                if(j>0){
                    LEFT[i][j]+=LEFT[i][j-1];
                }
            }
        }
        
        for(int i=0;i<m;i++){
            for(int j=n-1;j>=0;j--){
                RIGHT[i][j]=0;
                if(grid[i][j]==WALL){
                    continue;
                }
                
                if(grid[i][j]==ENEMY){
                    RIGHT[i][j]=1;
                }
                
                if(j+1<n){
                    RIGHT[i][j]+=RIGHT[i][j+1];
                }
            }
        }
        
        int max =0;
        for(int i=0;i<m;i++){
            for(int j =0;j<n;j++){
                if(grid[i][j]==BLANK)
                max = Math.max(max,(UP[i][j]+DOWN[i][j]+LEFT[i][j]+RIGHT[i][j]));
            }
        }
        return max;
    }
}
View Code

 

位操作:

664. Counting Bits

https://www.lintcode.com/problem/counting-bits/description?_from=ladder&&fromId=16

技术图片
public class Solution {
    /**
     * @param num: a non negative integer number
     * @return: an array represent the number of 1‘s in their binary
     */
    public int[] countBits(int num) {
        // write your code here
        int[] f = new int[num+1];
        f[0]=0;
        for(int i=1;i<=num;i++){
            f[i]=f[i>>1]+i%2;
        }
        return f;
    }
}
View Code

 

397. Longest Continuous Increasing Subsequence

https://www.lintcode.com/problem/longest-continuous-increasing-subsequence/description?_from=ladder&&fromId=16

技术图片
public class Solution {
    /**
     * @param A: An array of Integer
     * @return: an integer
     */
    public int longestIncreasingContinuousSubsequence(int[] A) {
        // write your code here
        if(A==null || A.length==0){
            return 0;
        }
        
        int incCount=1;
        int delCount = 1;
        
        int res = 1;
        for(int i=1;i<A.length;i++){
            if(A[i]==A[i-1]){
                continue;
            }
            if(A[i]>A[i-1]){
                incCount++;
                delCount = 1;
            }else{
                incCount =1;
                delCount++;
            }
            
            res = Math.max(res,Math.max(incCount,delCount));
        }
        
        return res;
    }
}
View Code

 

以上是关于动态规划2的主要内容,如果未能解决你的问题,请参考以下文章

应对笔试手写代码,如何准备动态规划?

应对笔试手写代码,如何准备动态规划?

应对笔试手写代码,如何准备动态规划?

算法动态规划 ① ( 动态规划简介 | 自底向上的动态规划示例 | 自顶向下的动态规划示例 )

算法动态规划 ① ( 动态规划简介 | 自底向上的动态规划示例 | 自顶向下的动态规划示例 )

动态规划-第二节:动态规划之背包类型问题