放苹果

题目描述:

把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。

Input

第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。

Output

对输入的每组数据M和N,用一行输出相应的K。

Sample Input

1
7 3

Sample Output

8

话不多说,上AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
    int a[15][15];	//dp数组
    //a[n][m]的意义就是在n个盘子里放m个苹果
    for (int i = 1; i <= 10; ++i)
        for (int j = 0; j <= 10; ++j)
        {
        //如果苹果数为0,方法只有一种: 不放
            if(!j)
                a[i][j] = 1;
        //如果只有一个盘子,也只有一种放法,就是把所有苹果放这里
            else if(i == 1)
                a[i][j] = 1;
        /*
        如果有两个盘子,由于(a,b)与(b,a)等效,所以一个盘子至多放苹果数
        的一半,一个盘子至多能放多少个就是总的摆法,除以2会少算一个,所以+1
        */
            else if(i == 2)
                a[i][j] = j / 2 + 1;
        /*
        如果苹果数大于盘子数且盘子数大于3,那么这所有盘子只有两个状态:
        1.全都放了苹果
        2.不全都放了苹果
        对于情况2,它的结果就是dp[i-1][j],意思就是,不全都放苹果,那丢掉一个
        盘子,也没有影响。对于情况1,我们现在每个盘子都放一个苹果,那么它现在的
        的摆法数就等于dp[i][j-i]
        */
            else
            {
                if(j < i)
                    a[i][j] = a[i - 1][j];
                else
                    a[i][j] = a[i - 1][j] + a[i][j - i];
            }
        }
    int t, m, n;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d%d", &m, &n);
        printf("%d\n", a[n][m]);
    }
    return 0;
}