路徑問題(動態規划)


  • 1.最小路徑和(矩形)

給定一個只含非負整數的m*n網格,找到一條從左上角到右下角的可以使數字和最小的路徑。

注:你在同一時間只能向下或者向右移動一步

樣例1:
1 3 1

1 5 1

4 2 1

輸出:7

樣例2:

1 3 5 9 
8 1 3 4 
5 0 6 1 
8 8 4 0 

輸出:12

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int m = sc.nextInt();
		int n = sc.nextInt();
		int temp[][] = new int[m][n];
		for(int i = 0; i < m; i++){
			for(int j = 0; j < n; j++){
				temp[i][j] = sc.nextInt();
			}
		}
		System.out.print(minpath(temp));
	}
	
	public static int minpath(int a[][]) {
		
		if(a == null){
			return -1;
		}
		int m = a.length;
		int n = a[0].length;
		int dp[][] = new int[m][n];
		dp[0][0] = a[0][0];
		for(int i = 1; i < m; i++){
			dp[i][0] = dp[i - 1][0] + a[i][0];
		}
		for(int j = 1; j < n; j++){
			dp[0][j] = dp[0][j - 1] + a[0][j];
		}
		for(int i = 1; i < m; i++){
			for(int j = 1; j < n; j++){
				dp[i][j] = Math.min(dp[i - 1][j] + a[i][j], dp[i][j - 1] + a[i][j]);
			}
		}
		return dp[m - 1][n - 1];		
	}
}

 

  • 2.最小路徑和(三角形)

給定一個三角形,找出自頂向下的最小路徑和。每一步只能移動到下一行中相鄰的結點上。

樣例:給定三角形

[2], 
[ 3,4],
[ 6,5,7],
[ 4,1,8,3]
 
自頂向下的最小路徑和為  11(即,2 + 3 + 5 + 1 = 11)。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int H = sc.nextInt();
		List<List<Integer>> triangle = new ArrayList<>();
		for(int i = 0; i < H; i++){
			List<Integer> list = new ArrayList<Integer>();
			for(int j = 0; j <= i ; j++){				
				list.add(sc.nextInt());
			}
			triangle.add(list);
		}
		System.out.print(minpath(triangle));
	}
	
	public static int minpath(List<List<Integer>> triangle) {
		
		if(triangle == null || triangle.size() == 0){
			return 0;
		}
		int dp[][] = new int[triangle.size()][triangle.size()];
		for(int i = 0; i < triangle.size(); i++){
			dp[triangle.size() - 1][i] = triangle.get(triangle.size() - 1).get(i);
		}
		for(int i = triangle.size() - 2; i >= 0; i--){
			for(int j = 0; j <= i; j++){
				dp[i][j] = Math.min(dp[i + 1][j] + triangle.get(i).get(j), dp[i + 1][j + 1] + triangle.get(i).get(j));
			}
		}
		return dp[0][0];		
	}
}

  

 

  • 3.不同路徑個數

a.給定一個m*n網格,統計從左上角到右下角的所有路徑個數。

注:你在同一時間只能向下或者向右移動一步

樣例1:

輸入: m = 3, n = 2
輸出: 3

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int m = sc.nextInt();
		int n = sc.nextInt();
		int temp[][] = new int[m][n];
		System.out.print(countpath(temp));
	}
	
	public static int countpath(int a[][]) {
		
		int m = a.length;
		int n = a[0].length;
		int dp[][] = new int[m][n];
		for(int i = 0; i < m; i++){
			dp[i][0] = 1;
		}
		for(int j = 0; j < n; j++){
			dp[0][j] = 1;
		}
		for(int i = 1; i < m; i++){
			for(int j = 1; j < n; j++){
				dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
			}
		}
		return dp[m - 1][n - 1];		
	}
}

 b.給定一個m*n網格,統計從左上角到右下角的所有路徑個數(考慮圖中有障礙物)。

注:障礙物和無障礙物可以分別用 1 和 0 來表示。

 

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int m = sc.nextInt();
		int n = sc.nextInt();
		int temp[][] = new int[m][n];
		for(int i = 0; i < m; i++){
			for(int j = 0; j < n; j++){
				temp[i][j] = sc.nextInt();
			}
		}
		System.out.print(countpath(temp));
	}
	
	public static int countpath(int a[][]) {
		
		int m = a.length;
		int n = a[0].length;
		int dp[][] = new int[m][n];
		for(int i = 0; i < m; i++){
			if(a[i][0] == 1){
				break;
			}
			dp[i][0] = 1;
		}
		for(int j = 0; j < n; j++){
			if(a[0][j] == 1){
				break;
			}
			dp[0][j] = 1;
		}
		for(int i = 1; i < m; i++){
			for(int j = 1; j < n; j++){
				if(a[i][j] == 0){
					dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
				}				
			}
		}
		return dp[m - 1][n - 1];		
	}
}

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM