1. 程式人生 > >POJ3014 Cake Pieces and Plates【整數劃分+DP】

POJ3014 Cake Pieces and Plates【整數劃分+DP】

Cake Pieces and Plates
Time Limit: 5000MS Memory Limit: 131072K
Total Submissions: 6810 Accepted: 2168
Case Time Limit: 1000MS

Description

kcm1700, ntopia, suby, classic, tkwons, and their friends are having a birthday party for kcm1700. Of course, there is a very large birthday cake. They divide the birthday cake into undistinguishable pieces and put them on identical plates. kcm1700 is curious, so he wants to know how many ways there are to put m cake pieces on n plates.

Input

In the only input line, there are two integers n, m (1 ≤ n, m ≤ 4 500), which are the number of the plates and the number of the cake pieces respectively.

Output

If the number of ways is K, just output K mod 1000000007 because K can be very large.

Sample Input

3 7

Sample Output

8

Hint

There are 8 ways to fill 3 plates with 7 cakes, namely (0,0,7), (0,1,6), (0,2,5), (0,3,4), (1,1,5), (1,2,4), (1,3,3), (2,2,3).

Source

POJ Monthly--2006.09.29, Kim, Chan Min ([email protected])

問題連結POJ3014 Cake Pieces and Plates
問題簡述
    求將m塊蛋糕放進n個盤子裡的方案數。
問題分析
    這個問題是整數劃分問題,用動態規劃來實現。其關鍵是狀態轉換方程。
程式說明:(略)
參考連結:(略)
題記:(略)

AC的C語言程式(一維陣列)如下:

/* POJ3014 Cake Pieces and Plates */

#include <stdio.h>

#define MOD 1000000007
#define N 4500
int dp[N + 1];

int main(void)
{
    int n, m, i, j;
    while(~scanf("%d%d", &n, &m)) {
        dp[0]=1;
        for(i = 1; i <= m; i++)
            dp[i] = 0;
        for(i = 1; i <= n; i++)
            for(j = i; j <= m; j++)
                dp[j]=(dp[j] + dp[j - i]) % MOD;

        printf("%d\n", dp[m]);
    }

    return 0;
}

AC的C語言程式(二維陣列)如下:

/* POJ3014 Cake Pieces and Plates */

#include <stdio.h>
#include <string.h>

#define MOD 1000000007
#define N 4500
int dp[N + 1][N + 1];

void setdp(int n, int m)
{
    int i, j;
    memset(dp, 0, sizeof(dp));
    dp[1][1]=1;
    dp[1][0]=0;
    dp[0][1]=0;
    for(i = 1; i <= n; i++) {
        for(j = 1; j <= m; j++) {
            if(i > j)
                dp[i][j] = dp[i - 1][j];
            else if(i == j) {
                dp[i][j] = dp[i - 1][j] + 1;
                if(dp[i][j] >= MOD) /* 減法也許快一些 */
                    dp[i][j] -= MOD;
            } else if(i < j) {
                dp[i][j] = dp[i - 1][j] + dp[i][j - i];
                if(dp[i][j] >= MOD) /* 減法也許快一些 */
                    dp[i][j] -= MOD;
            }
        }
    }
}

int main(void)
{
    int n, m;
    while(~scanf("%d%d", &n, &m)) {
        setdp(n, m);
        printf("%d\n", dp[n][m]);
    }

    return 0;
}