成长轨迹58 【ACM算法之路 百炼poj.grids.cn】【递归】【1664:放苹果】

题目http://poj.grids.cn/practice/1664


真心是一道很经典很经典的题目,还是单独列出来

离散数学学过划分,但是那是集合划分,这道题是整数划分。
整数划分的思想如下:
整数划分问题是将一个正整数n拆成一组数连加并等于n的形式,且这组数中的最大加数不大于n。
     如6的整数划分为
     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

共11种。
【dfs代码】

View Code
 1 #include"iostream"
2 using namespace std;
3 int count=0;
4 int M,m,n;
5 void DFS(int k, int s,int t){
6 if( s==n ){
7 if(t==m) count++;
8 return ;
9 }
10 int i;
11 for(i=k;i>=0; i--){
12 if( t + i <= m )
13 {
14 DFS(i, s+1, t+i);
15 }
16 else
17 {
18 continue;
19 }
20 }
21 }
22
23 int main()
24 {
25 int i;
26 scanf("%d",&M);
27 while(M--)
28 {
29 count=0;
30 scanf("%d %d",&m, &n);
31 for(i=m;i>=0;i--)
32 {
33 DFS(i,1,i);
34 }
35 printf("%d\n",count);
36 }
37 return 0;
38 }


下面介绍一种通过递归方法得到一个正整数的划分数。

递归函数的声明为 int deal(int m, int n);其中m为要划分的正整数,n是划分中的最大加数(当n > m时,最大加数为m),
     1 当m = 0 或 n = 1时,deal的值为1,可根据上例看出,只有一个划分1 或 1 + 1 + 1 + 1 + 1 + 1
     可用程序表示为if(n == 1 || m == 0) return 1;
    
     2 下面看一看m 和 n的关系。它们有三种关系
     (1) n > m
     在整数划分中实际上最大加数不能大于m,因此在这种情况可以等价为deal(m, m);
     可用程序表示为if(n > m) return deal(m, m);
     (2) n < m     这是最一般的情况,在划分的大多数时都是这种情况。
     从上例可以看出,设n = 4,那deal(6, 4)的值是最大加数小于4划分数和整数2的划分数的和。
     即 deal(6,4) = deal(6,3) + deal(2,4)
     因此,此时deal(n, m)可表示为deal(m, n - 1) + deal(m - n, n)
     (3) m = n
     这种情况可用递归表示为deal(m, n - 1) + 1,从以上例子中可以看出,就是最大加数为6和小于6的划分之和
     用程序表示为if(m == n) return (deal(m, n - 1) + 1);
     我们发现其实也可以满足上面(2)所推导的公式

按照整数划分的思想,将一个整数划分为若干(x<=m) 整数,按由大到小逐级递减的顺序排列,  这样保证了不会出现 5,1,1 和 1,5,1 这种相同的情况,根据这样的思路来建立一个递归关系。

【ac代码】

 1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int deal(int m,int n)
5 {
6 if(m==0||n==1)
7 return 1;
8 else if(n>m) return deal(m,m);
9 else
10 return deal(m,n-1)+deal(m-n,n);
11 }
12
13 int main()
14 {
15 int t;
16 scanf("%d",&t);
17 for(int i=0;i<t;i++)
18 {
19 int m,n;
20 scanf("%d %d",&m,&n);
21 printf("%d\n",deal(m,n));
22 }
23 return 0;
24 }
原文地址:https://www.cnblogs.com/zeedmood/p/2367808.html