划分数(白书P66)

   有n个无区别的物品,将他们划分成不超过m组,求出划分方法数模M的余数。

   定义dp[ i ][ j ],为 j 个数划分成 i 份的的方法数

   如果  j< i,那么不存在分成 i 份,每份都至少为1的方案,

        则有   dp[ i ][ j ]=dp[ i-1][ j ];

      如果 j> i,那么可以分成恰好分成 i 份的方案和少于 i 份的方案

   (1). 恰好分成 i 份,则每个每个份里面至少有一个物品,那我们可以现在每份当中分入一个物品,然后再将剩余的 j - i 个物品分到 i 份中,即dp[ i ][ j - i ];

   (2). 少于 i 份的方案:dp[ i-1][ j ]

       即:dp[ i ] [ j ]=dp[ i ][ j - i ]+dp[ i - 1][ j ];

 

 1     for(i=1;i<=m;i++)
 2     {
 3         for(j=0;j<=n;j++)
 4         {
 5             if(j<i)
 6                 dp[i][j]=dp[i-1][j];
 7             else
 8                 dp[i][j]=(dp[i-1][j]+dp[i][j-i])%M;
 9         }
10     }
11     printf("%d\n",dp[m][n]);

 

posted @ 2019-04-02 17:05  望天望海望秋色  阅读(171)  评论(0)    收藏  举报