描述:
把m個同樣的蘋果放在n個同樣的盤子里,允許有的盤子空著不放,問共有多少種不同的分法?(用K表示)5,1,1和1,5,1?是同一種分法。?
數據范圍:0≤m≤10,1≤n≤10?。
?
動態規劃 理解:
定義dp[m + 1][n + 1],可以理解為:將0 - m個蘋果放入1 - n 個盤子的中的方法,每一行,則為將i個蘋果放入1 - n個盤子中的方法數。
根據m和n的關系:
1、蘋果的數量少于盤子時,即 m < n? --> dp[i][j] = dp[i][i]
2、蘋果的數量大于等于盤子時,分兩種情況:
1) 沒有空盤子時,則從每個盤子中拿走一個蘋果,擺放的方法數是一樣的。dp[i][j] = dp[i - j][j]
? ? ? ?2) 有空盤子時,此種情況不太好理解:有一個空盤子時? dp[i][j] = dp[i][j - 1]。其實這里的有一個空盤子,是個遞歸的過程dp[i][j - 1] 包含了dp[i][j - 2],以此類推:dp[i][j - 1],包含了 j - 1,... , 1個空盤子的情況
--> 有空盤子時,dp[i][j] = dp[i][j - 1];
--> m >= n 時, dp[i][j] = dp[i - j][j] + dp[i][j - 1];
?
邊界條件:
1、0個盤子時,當然沒法擺了,只能是0: dp[i][0] = 0;
2、一個盤子時,所有的蘋果只能放到這一個盤子中:dp[i][1] = 1
3、0個蘋果時,所有盤子都是空的:dp[0][j] = 1;
?
#include <bits/stdc++.h>
using namespace std;
int main() {
int m, n;
while (cin >> m >> n) {
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0)); // m個蘋果,放到n個盤子中
// 0個盤子和一個盤子時,只有一種方法
for (int i = 0; i <= m; i++) {
dp[i][0] = 0;
dp[i][1] = 1;
}
// 0個蘋果時
for (int i = 0; i <= n; i++) {
dp[0][i] = 1;
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (i < j) {
dp[i][j] = dp[i][i];
} else {
dp[i][j] = dp[i - j][j] + dp[i][j - 1];
}
}
}
cout << dp[m][n] << endl;
}
return 0;
}
本文摘自 :https://www.cnblogs.com/

