description
把m個同樣的蘋果放在n個同樣的盤子裡,允許有的盤子空著不放,問共有多少種不同的分法?(用k表示)5,1,1和1,5,1 是同一種分法。
input
第一行是測試資料的數目t(0 <= t <= 20)。以下每行均包含二個整數m和n,以空格分開。1<=m,n<=10。
output
對輸入的每組資料m和n,用一行輸出相應的k。
sample input
1sample output7 3
8
誒,明明放棄了,但還是.....不說了
推出遞推式還是費了挺長時間的,弱成渣
入正題:就是一道整數劃分問題
首先,很容易發現是存在遞推關係的題目,然後就是慢慢地發現以下關係:
令f(m,n)表示:m個蘋果由
總數目不大於n的盤子中的蘋果相加所得 的方案數。
1.當m
2.當m=n時,會有兩種分法 ①:每個盤子各乙個,方案數目為1. ②:有乙個盤子不放,剩下的n-1個盤子放m個蘋果,方案數f(m,n-1)
即為方案數目:1+f(m,n-1)
3.當m>n時,也有兩種分法 ①:每個盤子都先分乙個,剩下的m-n個蘋果再分到n個盤子裡,方案數 f(m-n,n)
②:有乙個盤子不放,剩下的n-1個盤子放m個蘋果
,方案數f(m,n-1)
即為方案數目:f(m-n,n)+
f(m,n-1)
注意:n或m為1時,即f(1,n)或f(m,1)算是1種方案,n或m少於1時,不存在方案。
其實認真觀察一下就會發現情況2和3都是統一情況,但是n和m為1或0時都算是1方案。
遞推的**:
#include int f(int m, int n)
int main()
return 0;
}
但是這樣遞迴效率實在太低,不過題目資料量比較少還很好。
由於已經有了遞推方程,所以可以用dp做一下
#include #include using namespace std;
int main()
} printf("%d\n", dp[m][n]);
} return 0;
}
我們再認真思考了一下,其實可以發現,陣列可以由二維化為一維,即是使用陣列壓縮的方法
#include #include using namespace std;
int main()
; for (int i = 1; i <= n; i++)
}printf("%d\n", dp[m]);
} return 0;
}
poj 1664 放蘋果 劃分數
題意 中文題目,不解釋。題解 第一種方法是暴力深搜 列舉盤子1 n放蘋果數量的所有情況,不需要剪枝 將每次列舉的情況,即每個盤的蘋果數量,以字典序排序,然後存進set裡 以此去重像 5 1 1 和 1 5 1 這種相同情況。1 2 author wixson3 4 include 5 include...
poj1664放蘋果 遞迴
放蘋果time limit 1000ms memory limit 10000k total submissions 23149 accepted 14694 description 把m個同樣的蘋果放在n個同樣的盤子裡,允許有的盤子空著不放,問共有多少種不同的分法?用k表示 5,1,1和1,5,1...
poj 1664 放蘋果 遞推
解題思路 我們不妨令f m,n 表示m個蘋果放到n個盤子裡有多少種放法,下面對不同的情況給予討論 1 當盤子數為1的時候,只有一種放法就是把所有蘋果放到乙個盤子裡。2 當蘋果數為0的時候,也只有一種放法。3 當m n時,也分兩種情況討論,一種是至少有乙個盤子裡不放蘋果,這樣子就相當於f m,n 1 ...