poj1664 放苹果(分拆数)

放苹果

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 20000/10000K (Java/Other)
Total Submission(s) : 24   Accepted Submission(s) : 17
Problem 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
算法分析:求 n 分拆数开一个数列 a[N],a[i]<=a[i=1](1<=i<=m-1);
View Code
 1 #include<iostream>
2 #define N 11
3 using namespace std;
4
5 int a[N],count,m;
6
7 void work(int j)
8 {
9 int i,t;
10 if(j<=m)
11 {
12 count++;
13 }
14 else return ;
15 t=a[j];
16 for(i=a[j-1];i<=t/2;i++)
17 {
18 a[j]=i;
19 a[j+1]=t-i;
20 work(j+1);
21 }
22 }
23
24 int main()
25 {
26 int n,i,t;
27 cin>>t;
28 while(t--)
29 {
30 cin>>n>>m;
31 count=1;
32 for(i=1;i<=n/2;i++)
33 {
34 a[1]=i;
35 a[2]=n-i;
36 work(2);
37 }
38 cout<<count<<endl;
39 }
40 return 0;
41 }

 法二:dp 把 n 个苹果放到 m 个盘子中就是分两种情况,一种是每个盘子都满了,另一种是至少有一个盘子是空的。
 
View Code
 1 #include<iostream>
2 using namespace std;
3
4 int d(int n,int m)
5 {
6 if(n==1||m==1) return 1;
7 if(n<m) return d(n,n);
8 else if(n==m) return d(n,n-1)+1;
9 else return d(n,m-1)+d(n-m,m);
10 }
11
12 int main()
13 {
14 int test,n,m;
15 cin>>test;
16 while(test--)
17 {
18 cin>>n>>m;
19 cout<<d(n,m)<<endl;
20 }
21 return 0;
22 }
posted @ 2012-03-19 17:00  mtry  阅读(229)  评论(0编辑  收藏  举报