放苹果

把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个盘子里,盘子可以为空。直接搜吧,主要难点就是如何控制怎么才能筛选出不同的分法。
怎么筛呢?我们分析一波样例
0,0,7
0,1,6
0,2,5 、1,1,5
0,3,4、 1,2,4
1,3,3
2,2,3

看出规律来了吗??
后一个盘子的苹果数都 >= 前一个盘子的苹果数
根据这点咱们就可以得到答案。
因为最多才10个盘子,咱们就可以开一个数组,记录每个盘子的苹果数,后面的盘子的苹果数只要比前一个大就行,附上代码

import java.util.Scanner;

public class Main {
	int m,n,sum;
    int[] g = new int[15];
	public static void main(String[] args) {
		  Main s = new Main();
		  int  k;
		  Scanner cin = new Scanner(System.in);
		  k = cin.nextInt();
		  while(k>0)
		  {
			  k--;
			  s.sum=0;
			  s.init();  //g数组初始化
			  s.m = cin.nextInt();  //苹果数
			  s.n = cin.nextInt();  //盘子数
			  s.dfs(s.m,1);
			 System.out.println(s.sum);
		  }
	    }
	 public void init()
	 {
		 for(int i=0;i<15;i++)
		 {
			 g[i]=0;
		 }
	 }
	 public void dfs(int num,int top)
	 {
		 if(top==n)  //到最后一个盘子时
		 {
			 if(num>=g[top-1])    //判断剩下的苹果数是否比前一个盘子苹果数多  多的话分法+1
			 {
				  sum++;
			 }
			
			 return ;
		 }
		
		 for(int i=0;i<num;i++)
		 {
			 if(i>=g[top-1])
			 {
				 g[top]=i;
				 dfs(num-i,top+1);
				 g[top]=0;
			 }
			 
		 }
	 }
}
 

第二种解法:dp
我们多手动写几次就能找出规律来了,拿样例来说
7 3,那他的值就等于 7 2的值+4 3的值,所以可以定义一个二维数组来存
g[m][n] = g[m][n-1]+g[m-n][n]
但是还有一种情况 m-n的值比n的值更小,举个例子
g[4][3] = g[4][2]+g[1][3] 这是不成立的 ,因为g[1][3]这个值是不存在的(m>=n)
所以这个时候的规律就变成
g[m][n] = g[m][n-1]+g[m-n][m-n]
g[4][3] = g[4][2]+g[1][1] 成立 下面给代码

import java.util.Scanner;
public class Main {
	int m,n,sum;
    int[][] g = new int[15][15];
	public static void main(String[] args) {
		  Main s = new Main();
		  Scanner cin = new Scanner(System.in);
		  int k = cin.nextInt();
		  s.fig();
		  while(k>0)
		  {
			  k--;
			  s.sum=0;
			  s.m = cin.nextInt();  //苹果数
			  s.n = cin.nextInt();  //盘子数
			 System.out.println(s.g[s.m][s.n]);
		  }
	    }
	 public void fig()
	 {
		 g[0][0]=1;   //g[1][1] = g[1][0] +g[0][0]   先给它初始值 后面再变回来   
		                //你也可以不这样 但是需要在for循环里面加一些判断
		 for(int i=1;i<=10;i++)
		 {
			 for(int j=1;j<=i;j++)
			 {
				 if(i-j<j)
				  {
					g[i][j]=g[i][j-1]+g[i-j][i-j];
				  }
				  else
				  {
					g[i][j]=g[i][j-1]+g[i-j][j];
				  }	
			 }
		 }
		 g[0][0]=0;  //这里就改回来 
	 }
}
### 关于C语言中的“苹果”编程问题 在C语言中,“苹果”的问题是经典的算法练习之一,通常涉及组合数学的概念。这类题目旨在考察程序员对于循环、条件判断以及基本逻辑的理解。 #### 题目描述 给定m个相同的苹果入n个不同的盘子里的方法总数。假设每个盘子可以为空也可以不为空,问总共有多少种置方法?此问题可以通过动态规划或者递归来解决[^1]。 #### 动态规划解法分析 定义`f[i][j]`表示前i个盘子下j个苹果的方式数目,则状态转移方程如下: - 当第i个盘子为空时:`f[i][j]=f[i-1][j];` - 当第i个盘子非空时(即至少有一个苹果):`f[i][j]+=f[i][j-i];` 最终的结果保存在`f[n][m]`里。初始化条件为当只有一个盘子的时候只有一种方式来分配所有的苹果;而没有任何苹果的情况下也仅存在一种情况——所有盘子都为空。 下面是基于上述思路的一个简单实现例子: ```c #include <stdio.h> int f[100][100]; void init(int n, int m){ for(int i = 0 ; i <= n ; ++i) f[i][0] = 1; } int countWays(int n,int m){ if(m<0)return 0; if(f[m][n]!=-1)return f[m][n]; // 如果当前篮子数量大于等于苹果数,则可以直接把所有苹果在一个篮子里 if(n>=m)f[m][n]=(countWays(n,m-1)+countWays(n-m,m)); else f[m][n]=countWays(n,m-1); return f[m][n]; } int main(){ memset(f,-1,sizeof(f)); int n,m; scanf("%d%d",&n,&m); init(n,m); printf("%d\n",countWays(n,m)); } ``` 这段代码实现了通过记忆化搜索的方式来解决问题,并利用二维数组存储中间结果以减少重复计算的时间复杂度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值