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 (kcm1700@POJ)

问题链接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;
}

猜你喜欢

转载自www.cnblogs.com/tigerisland45/p/10177219.html