递归算法之放苹果问题-再想想

/*
1、放苹果
问题描述
把 M 个同样的苹果放在N 个同样的盘子里,允许有的盘子空着不放,问共有多少
种不同的分法?(用K 表示)注意:5,1,1 和1,5,1 是同一种分法。
输入数据
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含两个整数M 和N,以
空格分开。1<=M,N<=10。
输出要求
对输入的每组数据M 和N,用一行输出相应的K。
输入样例
1
7 3
输出样例
8
*/

 


#include<stdio.h>
int fun(int m,int n,int j);
void main()
{
 int n,m,s,i;
 scanf("%d",&i);
 while(i--)
 {
 scanf("%d%d",&m,&n); //m苹果数,n盘子数
 if(n>m) n=m; /*因为盘子是相同的,所以,盘子数>苹果数的情况与n=m的情况相同*/
 s=fun(m,n,0);
 printf("%d\n",s);
}
}
int fun(int m,int n,int j)
{
 int i,s=0;
 //if(n==1) return m>=j; //return m>=j;可改为if(m>=j) return 1;//防止重复,要求右面大于左面,上一个盘子放了j个苹果,这层的盘子要放大于j个苹果
 if(m<j) return 0;//减支进行优化,与下面不能互换,若互换,3盘子 4苹果 上一把0个苹果,还1个盘子
 if(n==1) return 1;
 for(i=j;i<m;i++) s+=fun(m-i,n-1,i); //与全排列,八皇后相比,这是新的地方,//0 _ _ + 1 _ _ + 2 _ _ + 3 _ _  + 4 _ _ + 5 _ _+..
 /*递归调用,先从m个苹果中拿出i个放在第一个盘子,
 再计算m-i个苹果放入n-1个盘子的问题
 (注意:为了不重复,放入下一个盘子的苹果数要大于等于i个)*/
 return s;
}

 

 

-----------------------------------------------------------------------------------------------------------------------------------

//by sun

/*
(7,3)=(7,2)+(4,3)
(7,2)至少一个为空,(7,2)包括(7,1)和(5,2)
(4,3)都不为空
*/

#include <iostream>
using namespace std;

int apple(int m,int n)
{
    if (m==0||n==1)
        return 1;
    if (m<n)
        return apple(m,m);
    else
        return apple(m-n,n)+apple(m,n-1);
}
int main()
{
    int n;
    cin>>n;
    while (n--)
    {
        int m,n;
        cin>>m>>n;
        cout<<apple(m,n)<<endl;
    }

    return 0;
}

 

-------------------------------------------------------------------------------

//未理解的算法

#include<stdio.h>

int M,N,K=0;
int b[100];
int a=0,k;
void apple(int t,int j)
{
 if(t==0&&a<=N) K++;
 else{
 for(int i=M;i>0;i--)
  if(t>=i&&i<=j)
  {
      t=t-i;
   a++;
   apple(t,i);
   a--;
   t=t+i;
  }
 }
  
}

 

void main()
{
    int t;
 scanf("%d",&t);
 for(int i=0;i<t;i++)
 {

     //printf("输入M N\n");
     scanf("%d %d",&M,&N);
  K=0;
     apple(M,M);
     printf("%d\n",K);
 }
}

 

----------------------------------------------------------------------------------------------

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值