動態規劃入門——數字三角形(Java)

動態規劃的概念對於新手來講枯燥難懂,就算看懂了,作題的時候依舊抓耳撓腮的毫無頭緒,這些比較難理解的算法,仍是須要根據例子來一步步學習和理解,從而熟練掌握,下面,我們就經過一個簡單的小例子來學習動態規劃:java

數字三角形(POJ1163)算法

    

    在上面的數字三角形中尋找一條從頂部到底邊的路徑,使得路徑上所通過的數字之和最大。數組

路徑上的每一步都只能往左下或 右下走。只須要求出這個最大和便可,沒必要給出具體路徑。 三角形的行數大於1小於等於100,數字爲 0 - 99網絡

    輸入格式:函數

    5      //表示三角形的行數    接下來輸入三角形學習

    7優化

    3   8spa

    8   1   03d

    2   7   4   4code

    4   5   2   6   5

    要求輸出最大和

 

我們來分析這道題:

1.須要有一個變量 n 來存儲輸入的行數

 

2.須要一個二維數組 a 來存儲輸入的數字三角形

 

3.須要另外一個一樣大小的二維數組 b,用來存儲到每一層的每個數的最短路徑,

例如:

到三角形的第三層,有兩條路會通過1,

因爲7+3=10<7+8=15,因此b數組的1的位置存儲的是最短路徑7—>3—>1等於11,

而在最兩邊的,就直接累加就ok了,7+3+8=18,7+8+0=15

 這也是這個程序的核心部分,代碼以下:

 

 

由於第一層跟a數組的第一層相同,因此i從1開始循環

 而後遍歷最後一層,求出最小值就ok啦

b數組最後的值

 

完整代碼以下:

 

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner sca = new Scanner(System.in);
		int n = sca.nextInt();
		int[][] a = new int[n][n];
		int[][] b = new int[n][n];
		int min;
		for(int i = 0;i<n;i++){
			for(int j = 0;j<=i;j++){
				a[i][j] = sca.nextInt();
			}
		}

		b[0][0] = a[0][0];
		for(int i = 1;i<n;i++){
			for(int j = 0;j<=i;j++){
				if(j==0)//左側,直接相加
					b[i][j] = b[i-1][j]+a[i][j];
				else if(j==i)//右側,直接相加
					b[i][j] = b[i-1][j-1]+a[i][j];
				else//中間,須要用min函數求通過這條路的最短路徑
					b[i][j] = Math.min(b[i-1][j-1],b[i-1][j])+a[i][j];
			}
		}

		min = b[n-1][0];
		for(int i = 1;i<b[n-1].length;i++){
			if(b[n-1][i]<min)
				min = b[n-1][i];
		}
		System.out.println(min);
	}
}

  

 

總結一下動態規劃的解題思路:

1,將原問題分解爲簡單的子問題,子問題求出來以後,原問題也就很容易獲得了

2,肯定狀態轉移方程

這道題的狀態轉移方程:

 

 

 

 

 

動態規劃通常可分爲線性動規,區域動規,樹形動規,揹包動規四類。
舉例:
線性動規:攔截導彈,合唱隊形,挖地雷,建學校,劍客決鬥等;
區域動規:石子合併, 加分二叉樹,統計單詞個數,炮兵佈陣等;
樹形動規:貪吃的九頭龍,二分查找樹,聚會的歡樂,數字三角形等;
揹包問題:01揹包問題,徹底揹包問題,分組揹包問題,二維揹包,裝箱問題,擠牛奶(同濟ACM第1132題)等;
應用實例:
最短路徑問題 ,項目管理,網絡流優化等;
以上例子,每類挑選一題或兩題練習便可
 
 
 
全部的算法都須要多加練習,應用起來才能駕輕就熟,但願個人這篇博客能給各位愛學習的同伴們帶去一些收穫,我也是新手,你們共同努力,加油!
相關文章
相關標籤/搜索