整数划分问题

来源:互联网 发布:unity保卫萝卜源码 编辑:程序博客网 时间:2024/05/18 22:52
整数划分问题

转自:http://www.cppblog.com/Darren/archive/2009/04/08/79245.html

数 n 的划分是将 n 表示成多个正整数之和的形式
划分可以分为两种情况:
A  划分的多个正整数中,正整数的数量是任意的
   这又可以分为划分的正整数中,正整数可以相同与不同两类

 1.  划分的多个正整数可以相同, 递推方程可以表示为:
 
     (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]
 
           dp[n][m]表示整数 n 的划分中,每个数不小于 m 的划分数。
           同理可证明该式。
 
 2.  划分的多个正整数互不相同,递推方程可以表示为:
     
     (1)    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)    dp[n][m]= dp[n][m+1]+ dp[n-m][m]
 
            dp[n][m]表示整数 n 的划分中,每个数不小于 m 的划分数。

B  划分的多个正整数中,正整数的数量是固定的
    
   把一个整数 n 无序划分成 k 份互不相同的正整数之和的方法总数。
   方程为:
   
   dp[n][k]= dp[n-k][k]+ dp[n-1][k-1];
   证明方法参考: http://www.mydrs.org/program/html/0369.htm
   另一种理解,总方法可以分为两类:
   第一类: 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]

0 0
原创粉丝点击