划分數問題


問題描述:有n個無區別的物品,將它們划分成不超過m組,求出划分方法數 

這是一道經典的不能再經典的題目,當然也有不同的定義方式,下面將從兩種方式來分析這個問題

》把n個同樣的蘋果放在m個同樣的盤子里,允許有的盤子空着不放,問共有多少種不同的分法?(用K表示,5,1,1和1,5,1 是同一種分法

放蘋果的問題乍看之下很復雜,盤子是一樣的,蘋果也是一樣的;只要每個盤子里面放的蘋果是一樣多的,不管順序如何最終得到的都是同一種分法。其實我們需要把問題簡化。就拿這個放蘋果的問題而言,我們只需要分兩種情況:有空盤子和沒空盤子。

1.有空盤子:f(n, m) = f(n, m-1)  //有空盤子很多人會有疑問,這不是只有一個空盤子的情況嗎?那2個3個空盤子呢?可以先思考一下

2.沒有空盤子:f(n, m) = f(n-m, m)  //沒有空盤子,我們可以看成先給每一個盤子放一個蘋果,則還剩下n-m個蘋果,剩下的問題就是把這n-m個蘋果放到m個盤子里的問題了。看到這里你是不是有點明白為什么第一種情況的遞推是那樣寫的,其實本質是一樣的,我們可以先看成先看成先讓一個盤子空着,還有m-1個盤子,剩下的問題就是吧這n個蘋果放到m-1個盤子里的問題。

因此:f(n, m) = f(n, m-1) + f(n-m, m)   ( n>=m) 

上面的表達式並不完整,當m<n時的情況沒有考慮,當m<n的時候,f(n, m)就相當於f(n, n)

寫到這里主要表達式基本上已經寫完了,但是遞推一般都要有邊界,稍微看一下就能找到,當只有一個盤子時明顯只有一種方法,另外沒有蘋果和只有一個蘋果的時候也只有一種放法。即當m=1或者n=0時,f(n, m) = 1      

綜上:

f(n, m) = 1  (m=1,n=0)

f(n, m) = f(n, n)   (n<m)

f(n, m) = f(n, m-1) + f(n-m, m)   ( n>=m) 

》將n划分成最大數不超過m的划分數

1.當 n=1,d為1,因為無論m為多少就只有1

2.當 m=1 時,d=1 ,由上例可知,當 n=4 時,d只有 1+1+1+1 這1種

3.當 n=m 時,又分為兩種情況:

  • 第一種就是包含m的時候,就只有 m 這一種。
  • 另外一種就是不包含 m ,那么最大數就為 m-1 ,有 d(n,m-1) 種

4.因此當 n=m 時,d(n , n)=1+ d(n,n-1)

5.當n < m 就相當於 d(n,n) 了

6.當 n > m 時,一種是不含m,為d(n,m-1)種,一種是含有m,有d(n-m,m)種

因此d(n,m)=d(n-m,m)+d(n,m-1)

(注意理解d(n-m,m),注意這里的前提是划分包含m,所以將m提出來一個,保證划分中一定會有m,剩下數字划分的和為n-m,而這n-m中可能不會出現m,也可能出現m,但由於我們已經提出了一個m,所以此處不用擔心m是否再出現。

第一個數為什么是(n-m),原因是提出一個m后,已經保證了划分中一定出現m,而n-m還沒有進行划分,這里忽略提出的m,對剩下的整數n-m進行划分,划分的最大值仍然是m)

 


前面之所以從不同的角度來分析是為了讓你能更好的理解狀態之間的遞推關系,懂了之后我們就能用動態規划的思想來解決這個問題:

定義題目為n的m划分數

(所有可能的情況都可以看作是把n划分成m份。只是有的是取0的)

那我們可以定義狀態:dp[i][j]表示 j 的 i 划分數 (注意,j的i划分表示的意義為 j固定,i可以取到1- i)

狀態轉移方程:1.j >= i時,dp[i][j] = dp[i-1][j]( j的i-1划分,相當於當前位取0的全部情況 ) + dp[i][j-i](當前位不取0,先把每一個置為1,再將剩下的j-i分下去)

       2.j < i時,dp[i][j] = dp[i-1][j];  當前位只能取0

核心代碼:

void solve()
{
    dp[0][0];
    for (int i = 0; i <= m; i++) {
        for (int j = 0; j <= n; j++) {
            if (j>=i)
                dp[i][j] = dp[i-1] + dp[i][j-1];
            else
                dp[i][j] = dp[i-1][j];    
        }
    }
    printf("%d\n", dp[m][n]);
}

參考博客:

https://www.cnblogs.com/zhangjiuding/p/7668938.html

https://blog.csdn.net/qq_33699981/article/details/68978736

https://blog.csdn.net/u012283461/article/details/52761238


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM