DFS y permutación y combinación (descripción en lenguaje C) # 2

Descripción del título:
Salida de todas las permutaciones no repetidas de números naturales de 1 an, es decir, la permutación completa de n. Se requiere que no aparezcan números repetidos en ninguna secuencia numérica generada.
Entrada de muestra:
3
Salida de muestra:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
Primer código de carga:
descripción en lenguaje C con retroceso 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;
}

Preste atención a dos puntos aquí
1.dfs (k + 1) no es k ++, ++ k;
2.i no abro el global, el valor se eliminará en la recursividad.
Principio:
Inserte la descripción de la imagen aquí
como se muestra en la figura, cuando encuentre un elemento que se ha utilizado para podar, tome el comienzo con 1 en [123] como ejemplo para
recorrer el 1, ingrese la búsqueda recursiva 123, mantenga 12 13 (excluya 11) Continuar buscando, mantener 123132 excluir (121, 122, 131, 133).
Lo anterior es el arreglo.
Suplemento: DFS recursivo con retroceso se utiliza para problemas de mochila.
El límite de tiempo determina si el DFS se puede utilizar para el problema de la mochila, es factible desde la búsqueda de la respuesta, pero es difícil AC desde la perspectiva del tiempo.
Mochila unidimensional:

#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;
}

Mochila bidimensional:

#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;
}

Ambos códigos se han probado en un círculo y serán TL cuando los datos sean lo suficientemente grandes, pero los resultados en sí mismos son correctos.
El árbol de elección o no en el artículo anterior también se puede utilizar para problemas de esquí.
Similar a tomar
dfs (i + 1, j-1)
dfs (i + 1, j + 1) de forma
recursiva, pero nuevamente, hay un límite de tiempo, tantos pueden ser DFS El problema solo puede ser DP al final.
De ninguna manera, adjunte una mochila unidimensional. Respuesta:

#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;
}

Resumen: DP es DP, incluso si DFS puede hacerlo, DP se ve mejor independientemente del código o la complejidad del tiempo.
Aunque originalmente fue permutación y combinación;

Los átomos son ilimitados en número y de forma diversa.
Todo está arreglado y combinado.
———— Demócrito

Supongo que te gusta

Origin blog.csdn.net/weixin_43736127/article/details/105949271
Recomendado
Clasificación