1. 程式人生 > >藍橋杯-數的劃分-動態規劃-java

藍橋杯-數的劃分-動態規劃-java

問題描述   將整數n分成k份,且每份不能為空,任意兩份不能相同(不考慮順序)。
  例如:n=7,k=3,下面三種分法被認為是相同的。
  1,1,5; 1,5,1; 5,1,1;
  問有多少種不同的分法。 輸入格式   n,k 輸出格式   一個整數,即不同的分法 樣例輸入 7 3 樣例輸出 4 {四種分法為:1,1,5;1,2,4;1,3,3;2,2,3;} 資料規模和約定

  6<n<=200,2<=k<=6

解題思路:有很多種解法這裡說一下用動態規劃來解

      動態規劃的核心就是圍繞狀態來說,剖析這道題

      建立一個二維陣列橫行代表將一個數拆幾份

      豎行代表要拆分的數那麼方案數=arr[n][k].

      我們要簡化狀態對於每一種分法我把它分成兩種情況

      1.分法裡至少有一個1  比如 5 = 1+2+2  5 = 1+1+3

      2.分法裡沒有1  比如 5 = 3+2 

      所以方案數=沒有1的所有分法+有1的所有分法

      先分析有至少有一個1的狀態:

          假設我要把10分成4份那麼至少有一個1
          的情況就是把9分成3份的所有分法

          我不管9是怎麼分的都是下面的情況

          第一份+第二份+第三份+1=10

          用程式碼表示:arr[i-1][j-1]

      再分析沒有1的狀態:

          還是我把10分成4份既然不含1

          我先從10中取出4個1

          1  1  1  1

          10裡還剩6我在把6分成4份

          我不管6到底怎麼分4份

          只要把1加上這4份就不含1

          用程式碼表示:arr[i-j][j]

      核心程式碼:arr[i][j] = arr[i-j][j]+arr[i-1][j-1]

      以下是程式碼:

import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
         Scanner scanner = new Scanner(System.in);
         while (scanner.hasNext()) {
int n = scanner.nextInt();
int k = scanner.nextInt();
int [][] arr = new int [201][7];
for (int i = 0; i < 201; i++) {
Arrays.fill(arr[i], 0);
}
for (int i = 0; i <201; i++) {
arr[i][1]=1;
}
for (int i = 2; i < 201; i++) {
for (int j = 1; j < 7; j++) {
if (j>i) {
arr[i][j]=0;
}else {
arr[i][j]=arr[i-j][j]+arr[i-1][j-1];
}
}
}
System.out.println(arr[n][k]);
}
}


}