AcWing 93. Implementar recursivamente enumeración combinada (recursiva)


Análisis de la complejidad temporal del tema : En el
video total, se menciona que el número calculado no supera los 100 millones, y generalmente no se agota el tiempo. Esta pregunta se calcula tomando 25 como base y 13 como la parte superior. El resultado se multiplica por 13 = 5200300 (13 es el m de esta pregunta)
porque todavía hay salida, cada combinación debe emitirse 13 veces como máximo . La
respuesta final * 5200300 13 = 67603900 **

Mi propio código se ha agotado, aunque se ha agotado, pero yo mismo lo reescribí cuidadosamente, ¡así que continúe trabajando en él la próxima vez!
Esto se basa en (AcWing 94. Realización recursiva de enumeración de permutación) pregunta 94 no (la regla de ordenar de pequeño a grande en cada línea) Esta pregunta necesita agregar código para hacer que el resultado sea de pequeño a grande.
Código de tiempo de espera

#include<iostream>//注意本题是   字典排序 
#include<cstdio>//时间是    n!
#include<cstring>
#include<algorithm>
using namespace std;

const int N=10;

int n,m;
int state[N];// 0 表示还没放数,1~n表示放了哪个数
bool used[N]; // true表示用过,false表示还未用过

void dfs(int u)
{
    
    
	if(u>m) //  因为输出为m个,所以当u=m+1时就可以进行输出 
	{
    
    
		for(int i=1;i<m;i++)//!!!与94题不一样的地方,这里会去掉不是顺序的输出 
		{
    
    
			if(state[i+1]<state[i])
			{
    
    
				return;
			}
		}
			
		for(int i=1;i<=m;i++){
    
    // 打印方案
			printf("%d ", state[i]);
		}
		puts("");
		return ;
		}
	
	
	 // 依次枚举每个分支,即当前位置可以填哪些数
	for(int i=1;i<=n;i++){
    
    
		if(!used[i]){
    
    
			state[u]=i;
			used[i]=true;
			dfs(u+1);
			
			//恢复现场
			state[u]=0;
			used[i]=false; 
		}
	}
}

int main()
{
    
    
	scanf("%d %d",&n,&m);
	dfs(1);
	return 0;
}

yDiagrama de
análisis de código total :
Inserte la descripción de la imagen aquí

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 30;

int n, m;
int state[N];//存储每次输出的数组 

void dfs(int u, int start)
{
    
    
    if (u-1 + n - start +1< m) return;  // 剪枝  (150->50ms)速度加快三倍  
    //每个数组最多可以输出(u-1 + n - start +1)个 ,如果它<m,这组数据已经不用再进行考虑了 (对应的是树中的!红错号)
    if(u>m) 
	{
    
    
        for (int i = 1; i <= m; i ++ ) printf("%d ", state[i]);
        puts("");
        return;
    }

    for (int i = start; i <= n; i ++ )//因为需要顺序输出,所以每次从start开始(对应第28行) 
    {
    
    
        state[u] = i;
        
        dfs(u + 1, i + 1);//与其他(递归)不同的是多了 i+1,因为这道题需要顺序输出,start每次都需要+1 
        state[u] = 0; // 恢复现场
    }
}

int main()
{
    
    
    scanf("%d%d", &n, &m);

    dfs(1, 1);

    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_47874905/article/details/114899496
Recomendado
Clasificación