POJ-1664

 
放苹果
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 30213   Accepted: 19053

Description

把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
 

本题可以看成典型的整数分解问题。将m个苹果放到n个盘子里时可以分为两种情况,我们设a(m,n)表示结果总数,当全部n个盘子都不为0时,即每个盘子至少有一个苹果,这时我们可以将总数看为a(m-n,n);当有一个空盘时,可以看做m个苹果放入n-1个盘子中,即a(m,n-1)(无需考虑多个空盘的情况,递归时自然会出现)。这时我们可得方程a(m,n)=a(m,n-1)+a(m-n,n)。下面我们来讨论几种特殊情况,首先就是m为1/0和n为1/0的情况,显而易见,a(m,1)、a(m,0)、a(1,n)、a(0,n)的结果皆为1。其次就是m<n时,a(m,n)的结果与a(m,m)的结果相同,故当m<n时,a(m,n)=a(m,m)。

我们也可以这样理解a(m,n-1)加一个空盘0即为a(m,n)含0的情况,a(m-n,n)在每一个盘子里加1个苹果即为a(m,n)且不会影响结果,这就是不含0的情况。所以a(m,n-1)和a(m-n,n)组成了a(m,n)即a(m,n)=a(m,n-1)+a(m-n,n)。

附AC代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int MAX=12;
 8 
 9 int a[MAX][MAX];
10 
11 int main(){
12     int i,j,t,m,n;
13     for(i=0;i<MAX;i++){
14         a[0][i]=1;
15         a[1][i]=1;
16         a[i][0]=1;
17         a[i][1]=1;
18     }
19     for(i=2;i<MAX;i++){
20         for(j=2;j<MAX;j++){
21             if(i>=j)
22             a[i][j]=a[i][j-1]+a[i-j][j];
23             else
24             a[i][j]=a[i][i];
25         }
26     }
27     while(~scanf("%d",&t)){
28         while(t--){
29             scanf("%d %d",&m,&n);
30             if(m>=n)
31             printf("%d\n",a[m][n]);
32             else
33             printf("%d\n",a[m][m]);
34         }
35     }    return 0;    
36 }

 

posted @ 2016-05-22 16:55  Kiven#5197  阅读(241)  评论(0编辑  收藏  举报