DFS et permutation et combinaison (description en langage C) # 1

Utilisez DFS pour trouver la combinaison

Premier regard sur le sujet: La
permutation et la combinaison sont des méthodes mathématiques couramment utilisées. La combinaison consiste à extraire r éléments de n éléments (aucun ordre et r≤n). Nous pouvons simplement comprendre n éléments comme des nombres naturels 1,2,…, n, prenez-leur n'importe quel nombre de r.

Vous devez maintenant sortir toutes les combinaisons.

Par exemple, n = 5, r = 3n = 5, r = 3, toutes les combinaisons sont:
123,124,125,134,135,145,234,235,245,345;
résoudre à nouveau le problème: DFS récursif sans retour en arrière

#include<stdio.h>
int n=0,r=0;
int a[25],b[20000];
int i=0,j=0,k=0,t=0,t1=0,t2=0;
void dfs(int i,int k)
{
    
    
if(i==n+1)
return;
i++;
//printf("i:%d t:%d k:%d\n",i,t,k);//用于检验
if(k==r)//位数达到时输出且返回上层
{
    
    for(j=0;j<r;j++)
{
    
    printf("%3d",a[j]);}
printf("\n");
return;
}
a[k]=i;//存入数组
dfs(i,k+1);//选入,此处i不必加入参数
dfs(i,k);//不选

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

Principe:
n <21 donne beaucoup d'espace de fonctionnement.
Avec la récursivité DFS, chaque nombre a deux choix: sélectionner la combinaison ou non;
Insérez la description de l'image ici
l'avantage de cette méthode est qu'il n'y a pas de problème de retour en arrière, et l'inconvénient est que c'est le temps- Comme on peut le voir sur la figure, cette méthode donne en fait la possibilité de différentes combinaisons de x chiffres, même si l'un n'est pas sélectionné, il est inclus à la fin. À partir du premier chiffre, il existe deux possibilités pour aucun chiffre. Quel que soit le nombre de chiffres, la complexité temporelle doit être de 2 ^ n. Vous pouvez l'utiliser en toute confiance lorsque n <21 (et ne vous inquiétez pas du problème de commande ).
Pour donner un contre-exemple. D'un
Insérez la description de l'image ici
certain point de vue, ce problème peut encore être résolu par une méthode de combinaison (le nombre de n est une combinaison de 2)

int abss(long long g,long long h)
{
    
    if(g>=h)
return g-h;
    else
        return h-g;
}
void dfs(long long i,long long k)
{
    
    if(i>n)
        return;
    i++;
    //printf("i:%lld k:%lld\n",i,k);
    if(k==2)
    {
    
    
        j=abss(b[1],b[0]);
        //printf("%lld %lld\n",b[0],b[1]);
        if(j==c)
            sum++;

        return;
    }
    b[k]=a[i];
    dfs(i,k+1);
    dfs(i,k);
}

Après avoir modifié les conditions, la version est soumise au TL dans les trois tests.
Par conséquent, cette méthode est facile à tuer directement lorsque la quantité de données est importante,
y compris le problème du sac à dos. Si nous pouvons lister toutes les combinaisons possibles, le problème naturel sera résolu, mais en raison de contraintes de temps, cela ne permet pas grand-chose. Il ne peut s'agir que de DP, ou d'utiliser DFS avec retour en arrière .
Le problème de la disposition est le même, et il doit ramener le DFS en arrière .
(Deux exemples de questions proviennent de Luogu.)

Je suppose que tu aimes

Origine blog.csdn.net/weixin_43736127/article/details/105563197
conseillé
Classement