ACM PKU 1664 放苹果 类似整数划分问题的递归

ACM PKU 1664 放苹果 类似整数划分问题的递归

http://acm.pku.edu.cn/JudgeOnline/bbs?problem_id=1664  

放苹果  
Time Limit:1000MS  Memory Limit:10000K
Total Submit:6074 Accepted:3764  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
17 3

Sample Output
8

Source
lwx@POJ




看到这道题立即想到了递归的经典案例:整数划分问题。 

将正整数n表示成一系列正整数之和:n=n1+n2+…+nk, 
其中n1≥n2≥…≥nk≥1,k≥1。 
正整数n的这种表示称为正整数n的划分。求正整数n的不 
同划分个数。 
例如正整数6有如下11种不同的划分: 
6; 
5+1; 
4+2,4+1+1; 
3+3,3+2+1,3+1+1+1; 
2+2+2,2+2+1+1,2+1+1+1+1; 
1+1+1+1+1+1。 

  将最大加数x不大于m的划分个数记作q(n,m) 
有 
                       1                                      n=1 || m=1 
q(n,m)  =  {       q(n,n)                                n<m 
                       1+q(n,n-1)                         n=m 
                        q(n,m-1)+q(n-m,m)            n>m>1  

重点在n>m>1的情况。  
呵呵,当时我还花了好些功夫才理解到哦,真是精妙。有了这一点经验,放苹果的问题就容易了,我们也有递归式 
将在m个盘中放n个苹果记作fun(m,n),且不能有空盘。(题目中的可以有空盘 不方便递归,我们循环累加) 
对于fun(m,n) 
                      1                                 n=1||m=n   
resulut   =       0                                 n<m 
                      ∑ fun(n-m,i)                   n>=m   , i=1..n  

当n>=m时,是不是方法和整数划分问题的n>m>1时很像呢?呵呵  


于是我们得到代码 
 1 #include  " stdio.h "  
 2 int  fun( int  m, int  n) 
 3
 4int i,result; 
 5if(n==1||m==n) return 1
 6  else if(n<m) return 0
 7  else 
 8  
 9   result=0
10   for(i=1;i<=n;i++
11    result+=fun(n-m,i); 
12   return result; 
13  }
 
14}
 
15 void  main() 
16
17int T,m,n,k,i; 
18int result=0
19scanf("%d",&T); 
20while(T--
21
22  scanf("%d %d",&m,&n); 
23  for(i=1;i<=n;i++
24  result=result+fun(m,i); 
25  printf("%d\n",result); 
26}
 
27}
 
28

你可能感兴趣的:(ACM PKU 1664 放苹果 类似整数划分问题的递归)