java動態規划問題


這里是簡單的動態規划問題。其實,如果我們學過數據結構,應該就接觸過動態規划問題,當時一直沒有反應過來。我們求最小生成樹用的是貪婪算法。而求最短路徑就是動態規划。從一個點出發,到另外每個點的最短距離。在求最短路徑問題中,取一點,然后與選取與這個點連接的,最小的一條邊,把這個點標上,然后求與標上點的連接的點的最短路徑。我們先來看這道題目吧

1.題目描述

將一個由N行數字組成的三角形,如圖所以,設計一個算法,計算出三角形的由頂至底的一條路徑,使該路徑經過的數字總和最小。

 

我們可以把這個橫過來看變成

7

3  4

8  5  0

2  7  4  4

4  5  2  6  5

從頂部到底部,只能從7走到3,或者8,然后從3走到8和1,8走到1和0   。。。。

我們自己計算最小路徑怎么算呢。假如從7出發,我們選擇與他們兩個的最長的一個,這是貪婪法,但是貪婪法有些時候不適用,比如這個圖,7的話,貪婪選最小的選3,但是最短路徑不是這條。

這道題目就要用到動態規划,我從底到頂部,依次求出從底部到上一層的最短路求出來。每次求最短路徑,再記錄下來就行。這道題目簡單的地方就是上層的點到下層的路只有兩條。

也就是說共有5層,用一個tem[][]來存放從底層到這個點的最短路徑,那么第5層從底到自己最短路徑還是本身,4,5,2,6,5。第四層的就是temp[4][j]  =  temp[4][j]  +  Min{temp[5][j],temp[5][j+1]},只有這兩條路與上一層直接相連,就能直接標上。同理遞歸調用。。。

2.輸入描述

7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

3.輸出描述:

輸出每個點的從底部到這一點的最短路徑,都記錄下來。

17   
10   14   
14    7    6    
6      9    6    9    
4      5    2    6    5  

4.代碼示例:

package a;

import java.util.Scanner;

public class DP {
	static int qipan[][] = new int[5][5];
	static int temp[][] = new int[5][5]; //用來存放的最短路徑的
	public static void main(String[] args) {
		Scanner scn = new Scanner(System.in);
		for(int i=0;i<5;i++) {
			for(int j=0;j<=i;j++) {
				qipan[i][j] = scn.nextInt();
				temp[i][j] = qipan[i][j];
			}
		}
		dp(qipan,4);//把棋盤的第5層開始求。第5層最短路是本身,數組下標是4
		
		//輸出棋盤
		for(int i=0;i<5;i++) {
			for(int j=0;j<=i;j++) {
				System.out.printf("%-4d",temp[i][j]);
			}
			System.out.println();
		}
		
		//輸出路徑,這部分代碼只是用來輸出路徑的,調用print路徑
		temp[0][0] = -1;
		print(temp,0);
		for(int i=0;i<5;i++) {
			for(int j=0;j<=i;j++) {
				if(temp[i][j] ==-1) {
					System.out.printf("%-4d",qipan[i][j]);
				}else {
					System.out.printf("%-4d",0);
				}
				
			}
			System.out.println();
		}
	}
	private static void print(int[][] temp, int k) {
		
		if( k==4 ) {
			return;
		}
		for(int i=0;i<=k;i++) {
			if(temp[k][i]==-1) {
				if(temp[k+1][i]<temp[k+1][i+1]) {
					temp[k+1][i] = -1;
				}else {
					temp[k+1][i+1] = -1;
				}
			}
		}
		print(temp, k+1);
	}
	private static void dp(int[][] qipan, int k) {
		if(k ==0) {
			return;
		}
		for(int j=0;j<k;j++) {
			temp[k-1][j] = temp[k-1][j] + Math.min(temp[k][j], temp[k][j+1]);
		}
		dp(qipan, k-1);
	}
}

 


免責聲明!

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



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