1.將n劃分成不大於m的劃分法:
1).若是劃分多個整數可以存在相同的:
dp[n][m]= dp[n][m-1]+ dp[n-m][m] dp[n][m]表示整數 n 的劃分中,每個數不大於 m 的劃分數。
則劃分數可以分為兩種情況:
a.劃分中每個數都小於 m,相當於每個數不大於 m- 1, 故劃分數為 dp[n][m-1].
b.劃分中有一個數為 m. 那就在 n中減去 m ,剩下的就相當於把 n-m 進行劃分, 故劃分數為 dp[n-m][m];
2).若是劃分多個不同的整數:
dp[n][m]= dp[n][m-1]+ dp[n-m][m-1] dp[n][m]表示整數 n 的劃分中,每個數不大於 m 的劃分數。
同樣劃分情況分為兩種情況:
a.劃分中每個數都小於m,相當於每個數不大於 m-1,劃分數為 dp[n][m-1].
b.劃分中有一個數為 m.在n中減去m,剩下相當對n-m進行劃分,
並且每一個數不大於m-1,故劃分數為 dp[n-m][m-1]
2.將n劃分成k個數的劃分法:
dp[n][k]= dp[n-k][k]+ dp[n-1][k-1];
方法可以分為兩類:
第一類: n 份中不包含 1 的分法,為保證每份都 >= 2,可以先拿出 k 個 1 分
到每一份,然後再把剩下的 n- k 分成 k 份即可,分法有: dp[n-k][k]
第二類: n 份中至少有一份為 1 的分法,可以先那出一個 1 作為單獨的1份,剩
下的 n- 1 再分成 k- 1 份即可,分法有:dp[n-1][k-1]。
前面是摘抄他人的,寫的還不錯,就沒必要自己寫了……下面的劃分是我在做nyist 571時自己想的,題目只說了要前幾種劃分和奇數的劃分,沒有要求偶數的,我也就沒去寫了,反正奇數劃分和偶數劃分是大同小異,相信看了下面奇數的劃分,偶數的劃分寫出來應該不成問題!
3.將n劃分成若干個奇數或偶數的和:
f(n,k)表示將n劃分成不大於k的奇數之和的種數。
當k=1或者k=2時,可以用來劃分的奇數只有1,所以種數也只能是一種。
當k>n的時候,多出的部分根本劃分不到,所以種數為:f(n,n)。
當k==n的時候考慮n的奇偶性,若為奇數本身就是一種劃分(偶數就不用考慮本身了),然後再加上小於n的奇數的劃分就行了。
當k<n的時候,考慮k的奇偶性,再考慮含不含k的情況。
具體看代碼中的f3函數。
要有自己的思考,不能老是死記別人的東西!!!自己也許能想出更好的解決辦法,加油!!!!
#include <iostream>using namespace std;int f1(int n,int k){if(n==1||k==1) return 1;if(k>n) return f1(n,n);if(n==k) return 1+f1(n,k-1);return f1(n-k,k)+f1(n,k-1); //含m和不含m }int f2(int n,int k){if(k==1||n==k) return 1;if(k>n) return 0;return f2(n-k,k)+f2(n-1,k-1);//含1和不含1}int f3(int n,int k )//表示不大於k的奇數劃分 { if(k==1||k==2) return 1;//只有一種情況:n個1 if(n==k) if(n%2) return 1+f3(n,k-2);//n為奇數:本身+小於n的奇數劃分 else return f3(n,k-1); //n為偶數:小於n的奇數劃分 if(n<k) return f3(n,n); if(k%2) return f3(n-k,k)+f3(n,k-2); //n為奇數:含k的+不含k的奇數劃分 else return f3(n,k-1); //n為偶數:不含k的奇數劃分}int f4(int n,int k){if(k==1&&n==1) return 1;if(k==1&&n>1) return 0;if(k>n) return f4(n,n);if(k==n) return 1+f4(n,k-1);return f4(n-k,k-1)+f4(n,k-1);//含k不含k且為不同,所以k-1 }int main(void){ int n,k; while(cin>>n>>k) { cout<<f1(n,n)<<endl;//將n劃分成最大數不超過k的劃分數。 cout<<f2(n,k)<<endl;//將n劃分成k個正整數之和的劃分數 cout<<f1(n,k)<<endl;//將n劃分成最大數不超過k的劃分數。 cout<<f3(n,n)<<endl;//將n劃分成若干個奇正整數之和的劃分數。 cout<<f4(n,n)<<endl<<endl;//將n劃分成若干不同整數之和的劃分數。 }}