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

Description du titre:
affiche toutes les permutations non répétées de nombres naturels de 1 à n, c'est-à-dire la permutation complète de n. Il est nécessaire qu'aucun nombre répété n'apparaisse dans une séquence de nombres générée.
Exemple d'entrée:
3
Exemple de sortie:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
Premier code de téléchargement:
description en langage C avec retour en arrière DFS

#include<stdio.h>
int n=0;
int k=0,l=0,m=0;
int a[100];
int b[100];
void dfs(int k)
{
    
    int i=0;
    if(k==n){
    
    
        for(i=0;i<n;i++)
        printf("%5d",a[i]);
        printf("\n");
        return;
    }
        for(i=1;i<=n;i++)
        if(b[i]==0)//这个数没用过
        {
    
    
        a[k]=i;//纳入数组
         b[i]=1;//标记使用
        dfs(k+1);//往下填
        b[i]=0;//回溯
        }
}
int main()
{
    
    scanf("%d",&n);
dfs(0);
    return 0;
}

Faites attention à deux points ici
1.dfs (k + 1) n'est pas k ++, ++ k;
2.i n'ouvrez pas le global, la valeur sera effacée dans la récursivité.
Principe:
Insérez la description de l'image ici
Comme le montre la figure, lorsque vous rencontrez un élément qui a été utilisé pour l'élagage, prenez le début avec 1 dans [123] comme exemple pour
boucler sur 1, entrez la recherche récursive 123, gardez 12 13 (excluez 11) Continuer la recherche, conserver 123 132 exclure (121, 122, 131, 133).
Ce qui précède est l'arrangement.
Supplément: Backtracking récursif DFS est utilisé pour les problèmes de sac à dos.
Le délai détermine si le DFS peut être utilisé pour le problème du sac à dos. Il est faisable à partir de la recherche de la réponse, mais il est difficile de AC du point de vue du temps.
Sac à dos unidimensionnel:

#include<stdio.h>
int n=0,m=0,x=0;
int a[103][3],b[15000];
int i=0,j=0,k=0,sum=0,l=0,p=0,y=0;
int c[101];
int max(int a,int b)
{
    
    
    if(a>=b)
        return a;
    else
        return b;
}
void dfs(int sum,int k,int i)
{
    
    
int z=0;
        int j=0;
for(j=i;j<=n;++j){
    
    
    if(c[j]==0)
              if(a[j][1]<=k)
        {
    
    z=1;
        c[j]=1;
        dfs(sum+a[j][0],k-a[j][1],i+1);
        c[j]=0;
        }
}
if(z==0)
    {
    
    y=max(y,sum);
    return;}
}
int main()
{
    
    int max=0;
scanf("%d %d",&m,&n);//m为重量限制,n为可选择数目
for(i=1;i<=n;i++)
{
    
    
    scanf("%d %d",&a[i][1],&a[i][0]);
}
dfs(0,m,1);
printf("%d",y);
return 0;
}

Sac à dos bidimensionnel:

#include<stdio.h>
int n=0,m=0,x=0;
int a[103][3],b[15000];
int i=0,j=0,k=0,sum=0,l=0,p=0,y=0;
int c[101];
int max(int a,int b)
{
    
    
    if(a>=b)
        return a;
    else
        return b;
}
void dfs(int sum,int k,int l,int i)
{
    
    
int z=0;
        int j=0;

for(j=i;j<=n;++j){
    
    
    if(c[j]==0)
              if(a[j][1]<=k&&a[j][2]<=l)
        {
    
    z=1;
        c[j]=1;
        dfs(sum+a[j][0],k-a[j][1],l-a[j][2],i+1);
        c[j]=0;
        }
}
if(z==0)
    {
    
    y=max(y,sum);
    return;}
}
int main()
{
    
    int max=0;
scanf("%d %d %d",&n,&m,&x);//n为可选择数目,m为数据限制1,x为数据限制2
for(i=1;i<=n;i++)
{
    
    
    scanf("%d %d %d",&a[i][0],&a[i][1],&a[i][2]);
}
dfs(0,m,x,1);
printf("%d",y);
return 0;
}

Les deux codes ont été testés dans un cercle, et ils seront TL lorsque les données sont suffisamment volumineuses, mais les résultats eux-mêmes sont bons.
L'arbre de choix dans l'article précédent peut également être utilisé pour les problèmes de ski.
Similaire à prendre
dfs (i + 1, j-1)
dfs (i + 1, j + 1)
récursivement, mais encore une fois, il y a une limite de temps, tant peuvent être DFS Le problème ne peut être que DP à la fin.
Pas question, attachez un sac à dos unidimensionnel. Réponse:

#include<stdio.h>
int dp[101][1005];
int max(int a,int b)
{
    
    
    if(a>=b)
        return a;
    else
        return b;
}
int main()
{
    
    int n=0,k=0,i=0,j=0,m=0;
int a[103],b[103];
scanf("%d %d",&n,&m);
for(i=1;i<=m;i++)
    scanf("%d%d",&a[i],&b[i]);
for(i=1;i<=m;i++)
   for(j=n;j>=0;j--)
   {
    
    
       if(a[i]<=j)
        dp[i][j]=max(dp[i-1][j],dp[i-1][j-a[i]]+b[i]);
        else
        dp[i][j]=dp[i-1][j];
   }
   printf("%d",dp[m][n]);
    return 0;
}

Résumé: Le DP est DP, même si DFS peut le faire, DP est meilleur quel que soit le code ou la complexité temporelle.
Bien que ce soit à l'origine une permutation et une combinaison;

Les atomes sont illimités en nombre et de formes diverses.
Tout est arrangé et combiné.
———— Démocrite

Je suppose que tu aimes

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