zoukankan      html  css  js  c++  java
  • 路径最小问题

    问题

    给你一个二维数组,二维数组中的每个数都是正数,要求从左上角走到右下角,每一步只能向右或者向下。沿途经过的数字要累加起来。返回最小的路径

    经典的动态规划问题

    请记住这样一句话:每一个优美的动态规划,都来自原先暴力的尝试

    package class_08;
    
    public class Code_07_MinPath {
    
    	public static int minPath1(int[][] matrix) {
    		return process1(matrix, matrix.length - 1, matrix[0].length - 1);
    	}
    
    	public static int process1(int[][] matrix, int i, int j) {  // 暴力递归版
    		int res = matrix[i][j];
    		if (i == 0 && j == 0) {
    			return res;
    		}
    		if (i == 0 && j != 0) {
    			return res + process1(matrix, i, j - 1);
    		}
    		if (i != 0 && j == 0) {
    			return res + process1(matrix, i - 1, j);
    		}
    		return res + Math.min(process1(matrix, i, j - 1), process1(matrix, i - 1, j));
    	}
    
    	public static int minPath2(int[][] m) {  // 动态规划,把矩阵每个位置的信息记录下来,避免重复计算
    		if (m == null || m.length == 0 || m[0] == null || m[0].length == 0) {
    			return 0;
    		}
    		int row = m.length;
    		int col = m[0].length;
    		int[][] dp = new int[row][col];
    		dp[0][0] = m[0][0];
    		for (int i = 1; i < row; i++) {
    			dp[i][0] = dp[i - 1][0] + m[i][0];
    		}
    		for (int j = 1; j < col; j++) {
    			dp[0][j] = dp[0][j - 1] + m[0][j];
    		}
    		for (int i = 1; i < row; i++) {
    			for (int j = 1; j < col; j++) {
    				dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + m[i][j];
    			}
    		}
    		return dp[row - 1][col - 1];
    	}
    
    	// for test
    	public static int[][] generateRandomMatrix(int rowSize, int colSize) {
    		if (rowSize < 0 || colSize < 0) {
    			return null;
    		}
    		int[][] result = new int[rowSize][colSize];
    		for (int i = 0; i != result.length; i++) {
    			for (int j = 0; j != result[0].length; j++) {
    				result[i][j] = (int) (Math.random() * 10);
    			}
    		}
    		return result;
    	}
    
    	public static void main(String[] args) {
    		int[][] m = { { 1, 3, 5, 9 }, { 8, 1, 3, 4 }, { 5, 0, 6, 1 }, { 8, 8, 4, 0 } };
    		System.out.println(minPath1(m));
    		System.out.println(minPath2(m));
    
    		m = generateRandomMatrix(6, 7);
    		System.out.println(minPath1(m));
    		System.out.println(minPath2(m));
    	}
    }
    

    附加题

    给你一个数组arr,和一个整数aim。如果可以任意选择arr中的数字,能不能累加得到aim,返回true或者false。

    package class_08;
    
    public class Code_08_Money_Problem {
    
    	public static boolean money1(int[] arr, int aim) {
    		return process1(arr, 0, 0, aim);
    	}
    
    	public static boolean process1(int[] arr, int i, int sum, int aim) {
    		if (sum == aim) {
    			return true;
    		}
    		// sum != aim
    		if (i == arr.length) {
    			return false;
    		}
    		return process1(arr, i + 1, sum, aim) || process1(arr, i + 1, sum + arr[i], aim);
    	}
    
    	public static boolean money2(int[] arr, int aim) {
    		boolean[][] dp = new boolean[arr.length + 1][aim + 1];
    		for (int i = 0; i < dp.length; i++) {
    			dp[i][aim] = true;
    		}
    		for (int i = arr.length - 1; i >= 0; i--) {
    			for (int j = aim - 1; j >= 0; j--) {
    				dp[i][j] = dp[i + 1][j];
    				if (j + arr[i] <= aim) {
    					dp[i][j] = dp[i][j] || dp[i + 1][j + arr[i]];
    				}
    			}
    		}
    		return dp[0][0];
    	}
    
    	public static void main(String[] args) {
    		int[] arr = { 1, 4, 8 };
    		int aim = 12;
    		System.out.println(money1(arr, aim));
    		System.out.println(money2(arr, aim));
    	}
    
    }
    
  • 相关阅读:
    hdu 2222 Keywords Search
    Meet and Greet
    hdu 4673
    hdu 4768
    hdu 4747 Mex
    uva 1513 Movie collection
    uva 12299 RMQ with Shifts
    uva 11732 strcmp() Anyone?
    uva 1401
    hdu 1251 统计难题
  • 原文地址:https://www.cnblogs.com/horken/p/10706120.html
Copyright © 2011-2022 走看看