動態規劃經典例題(java代碼實現)

1、斐波那契數列

題目描述:

有一樓梯共M級,剛開始時你在第一級,若每次只能跨上一級或二級,要走上第M級,共有多少種走法?

輸入:

輸入數據首先包含一個整數N,表示測試實例的個數,然後是N行數據,每行包含一個整數M(1<=M<=40),表示樓梯的級

輸出:

對於每個冊數用例,請輸入不同走法的數量

   import java.util.Scanner;


public class Main{

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner scanner=new Scanner(System.in);
        int n=scanner.nextInt();//有n組數據
        int []jl=new int[n];//用於記錄每組數據結果的數組
        for (int i = 0; i < n; i++) {
            int x=scanner.nextInt();
            jl[i]=dp(x-1);
        }
        for (int i = 0; i < jl.length; i++) {
            System.out.println(jl[i]);
        }
        
    }
    public static int  dp(int m) {
        int[]dp=new int[m+1];
        dp[0]=1;
        dp[1]=1;
        for (int i = 2; i <=m; i++) {
            dp[i]=dp[i-1]+dp[i-2];
        }
        return dp[m];
    }

}

2、數塔問題

題目描述:

在講述DP算法的時候,一個經典的例子就是數塔問題,它是這樣描述的:

有如下所示的數塔,要求從頂層走到底層,若每一步只能走到相鄰的結點,則經過的結點的數字之和最大是多少?

輸入:

輸入數據首先包括一個整數C,表示測試實例的個數,每個測試實例的第一行是一個整數N(1 <= N <= 100),表示數塔的高度,接下來用N行數字表示數塔,其中第i行有個i個整數,且所有的整數均在區間[0,99]內。

輸出:

對於每個測試實例,輸出可能得到的最大和,每個實例的輸出佔一行。

import java.util.Scanner;


public class Main{

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner scanner=new Scanner(System.in);
        int n=scanner.nextInt();
        int[]jl=new int[n];
        for (int k = 0; k < n; k++) {
            int x=scanner.nextInt();
            int[][]arr=new int[x][];
            for (int i = 0; i < x; i++) {
                arr[i]=new int[i+1];
                for (int j = 0; j <= i; j++) {
                    arr[i][j]=scanner.nextInt();
                }
            }
            jl[k]=dp(arr, 0, 0);
        }
        for (int i = 0; i < jl.length; i++) {
            System.out.println(jl[i]);
        }
        
    }
    public static int dp(int[][]arr,int i,int j) {
        int rowCount=arr.length;//行數
        int columCount=arr[rowCount-1].length;//最後一行列數
        int[][]dp=new int[rowCount][columCount];
        for (int k = 0; k < columCount; k++) {
            dp[rowCount-1][k]=arr[rowCount-1][k];
        }
        for (int k = rowCount-2; k >=0; k--) {
            for (int l = 0; l <= k; l++) {
                dp[k][l]=Math.max(dp[k+1][l], dp[k+1][l+1])+arr[k][l];
            }
        }
        return dp[i][j];
    }
}

3、矩陣取數問題

題目描述:

一個N*N矩陣中有不同的正整數,經過這個格子,就能獲得相應價值的獎勵,從左上走到右下,只能向下向右走,求能夠獲得的最大價值。

例如:3 * 3的方格。

1 3 3

2 1 3

2 2 1

能夠獲得的最大價值爲:11。

輸入:

第1行:N,N爲矩陣的大小。(2<=N<=500)

第2-N+1行:每行N個數,中間用空格隔開,對應格子中獎勵的價值。(1<=N[i]<=10000)

輸出:

輸出能夠獲得的最大值。

輸入樣例:

3

1 3 3

2 1 3

2 2 1

輸出樣:

11

import java.util.Scanner;


public class Main{

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		         Scanner scan = new Scanner(System.in);
		         int n = scan.nextInt();
		         int[] dp = new int[n+1];
		         int[] readMax = new int[n+1];
		         for(int i=0;i<n;i++){
		             for(int k=1;k<n+1;k++){
		                readMax[k] = scan.nextInt();
		                //System.out.println("readMax["+k+"]="+readMax[k]);
		             }
		             for(int j=1;j<n+1;j++){
		                 dp[j] = Math.max(dp[j],dp[j-1])+readMax[j];
		                 //System.out.println("dp["+j+"]="+dp[j]);
		             }
		         }
		         System.out.println(dp[n]);
		     }

}

4、最大子段和

題目描述:

給定n個整數(可能有負數)組成的序列a1,a2,...,an,求該序列的最大子段和。如果所有整數都是負數,那麼定義其最大子段和爲0。

輸入:

輸入n個整數

輸出:

最大子段和

import java.util.Scanner;


public class dp08 {

	/**
	 * @param args
	 * 最大子段和
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[]arr={-2,1,-3,4,-1,2,1,-5,4};
		int[]dp=new int[arr.length];
		dp[0]=-1;//初始化數組
		int max=-1;//初始化最大值
		for (int i = 1; i < dp.length; i++) {
			dp[i]=Math.max(arr[i], arr[i]+dp[i-1]);
			max=dp[i]>max?dp[i]:max;//判斷當前最大和是否超過max;
		}
		System.out.println(max);
	}

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章