Descrição do título:
Saída de todas as permutações não repetidas de números naturais de 1 a n, ou seja, a permutação completa de n. É necessário que nenhum número repetido apareça em qualquer sequência numérica gerada.
Amostra de entrada:
3
Amostra de saída:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
Primeiro código de upload:
descrição da linguagem C com backtracking 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 atenção a dois pontos aqui
1.dfs (k + 1) não é k ++, ++ k;
2.i não abra o global, o valor será apagado na recursão.
Princípio:
Como mostrado na figura, quando você encontrar um elemento que foi usado para poda, pegue o início com 1 em [123] como um exemplo para fazer um
loop para 1, insira a pesquisa recursiva 123, mantenha 12 13 (exclua 11) Continue procurando, mantenha 123 132 exclude (121, 122, 131, 133).
O acima é o arranjo.
Suplemento: Backtracking DFS recursivo é usado para problemas de mochila.
O limite de tempo determina se o DFS pode ser usado para o problema da mochila. É viável na busca da resposta, mas é difícil fazer o AC do ponto de vista do tempo.
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 os códigos foram testados em um círculo e serão TL quando os dados forem grandes o suficiente, mas os resultados em si são bons.
A árvore de escolha ou não no artigo anterior também pode ser usada para problemas de esqui.
Semelhante a tomar
dfs (i + 1, j-1)
dfs (i + 1, j + 1)
recursivamente, mas, novamente, há um limite de tempo, tantos podem ser DFS O problema só pode ser DP no final.
De jeito nenhum, anexe uma mochila unidimensional. Resposta:
#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;
}
Resumo: O DP é DP, mesmo se o DFS puder fazer isso, o DP terá uma aparência melhor independentemente do código ou da complexidade do tempo.
Embora fosse originalmente permutação e combinação;
Os átomos são ilimitados em número e diversificados em forma.
Tudo está organizado e combinado.
———— Demócrito