Pon la manzana (solución de retroceso)

Coloque M manzanas idénticas en N platos idénticos y deje algunos platos vacíos ¿Cuántas divisiones diferentes hay? (Indicado por K) 5,1,1 y 1,5,1 son la misma división.
Entrada La
primera línea es el número de datos de prueba t (0 <= t <= 20). Cada línea a continuación contiene dos números enteros M y N, separados por espacios. 1 <= M, N <= 10.
Salida
Para cada conjunto de datos de entrada M y N, use una línea para generar el K correspondiente
 

Similar al artículo anterior sobre la división de enteros

Solo el número de placas se puede dividir en el número de números

Método 1: retroceso

La clave para dar marcha atrás es que el número de manzanas en cada plato en la parte posterior es mayor que el número de manzanas en el plato anterior para que no haya duplicaciones.

#include<iostream>
using namespace std;
int num[20];
int M,N,count;
void dfs(int n,int step)  //n表示剩余苹果数量   
{
	if(step>N||n<0)
		return ;
	if(n==0&&step==N)  //step==N表示前面 N个盘子都已经放好了苹果 
	{
		count++;
		return ;	
	}	
	for(int i=0;i<=M;i++)
	{
		if(i>=num[step-1])
		{
			num[step]=i;
			dfs(n-i,step+1);
			num[step]=0;
		}
	}
}
int main(void)
{
	cin>>M>>N;
	for(int i=0;i<=M;i++)
	{
		num[0]=i;    //第一个盘子数量的情况依次枚举
	    dfs(M-i,1); 
	}
	cout<<count<<endl;
	return 0;
}

2. Solución recursiva recursiva

#include<iostream>
using namespace std;

// 解题分析:
//        设f(m,n) 为m个苹果,n个盘子的放法数目,则先对n作讨论,
//        当n>m:必定有n-m个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响。即if(n>m) f(m,n) = f(m,m)  
//        当n<=m:不同的放法可以分成两类:
//        1、有至少一个盘子空着,即相当于f(m,n) = f(m,n-1);  
//        2、所有盘子都有苹果,相当于可以从每个盘子中拿掉一个苹果,不影响不同放法的数目,即f(m,n) = f(m-n,n).
//        而总的放苹果的放法数目等于两者的和,即 f(m,n) =f(m,n-1)+f(m-n,n) 
//    递归出口条件说明:
//        当n=1时,所有苹果都必须放在一个盘子里,所以返回1;
//        当没有苹果可放时,定义为1种放法。因为: 递归的两条路,第一条n会逐渐减少,终会到达出口n==1; 第二条m会逐渐减少,因为n>m时,我们会return f(m,m) 所以终会到达出口m==0.

int count(int m,int n)
{
	if(m==0||n==1)  //因为我们总是让m>=n来求解的,所以m-n>=0,所以让m=0时候结束,如果改为m=1,
	 return 1;  	//则可能出现m-n=0的情况从而不能得到正确解 
 
	if(n>m) return count(m,m);	//苹果的数量小于盘子的数量   这时候那么该问题就和m个苹果m个盘子的问题一样
	return count(m-n,n)+count(m,n-1);//苹果的数量大于盘子的数量  
}

int main(void)
{
	int m,n;
	cin>>m>>n;
	cout<<count(m,n);
	return 0;
}

 

Supongo que te gusta

Origin blog.csdn.net/a447332241/article/details/88033960
Recomendado
Clasificación