藍橋杯-數的劃分-動態規劃-java
例如: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]);
}
}
}