整數劃分(各種類型)nyist 571

來源:互聯網
上載者:User

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劃分成若干不同整數之和的劃分數。   }}

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.