Treinamento de algoritmo de teste e enumeração binária para T-> dfs

Descrição do problema
  Selecione alguns elementos de um conjunto de números inteiros de tamanho n para que sua soma seja igual ao valor T. Cada elemento pode ser selecionado apenas uma vez, nem todos.
Formato de entrada
  Um número inteiro positivo n na primeira linha indica o número de elementos no conjunto inteiro.
  N inteiros na segunda linha, separados por espaços.
  Um número inteiro T na terceira linha indica a soma a ser alcançada.
Formato de saída
  Existem várias linhas de saída e cada linha gera um conjunto de soluções, ou seja, os números selecionados são organizados na ordem da entrada.
  Se houver vários conjuntos de soluções, a saída prioritária não conterá o enésimo número inteiro; se contiver ou não, a saída prioritária não conterá o enésimo número inteiro, e assim por diante.
  A última linha gera o número total de soluções.
Entrada de amostra
  5
  -7 -3 -2 5 9
  0
Saída de amostra
  -3 -2 5
  -7 -2 9
  2
Tamanho e concordância dos dados
  1 <= n <= 22
  T <= maxlongint A soma
  de qualquer elemento do conjunto não excede o intervalo de comprimento
Ideia: Realizar dois casos de eleição de enumeração exponencial e não-eleição 
      A primeira versão simples do código dfs
#include <iostream> 
#include <cstdio> 
#include <algorithm> 
#include <stack> 
#include <cstring> 
#include <iomanip> 
#include <cmath> usando o namespace std; const int N = 25 ; int n, m, ans;
int a [N], st [N];
bool vis [N]; void dfs ( int u, int step, int s) 
{ if (u == - 1 ) 
    { if (s == m && step> = 1

 

 




    
        ) 
        { 
            ans ++ ;
             for ( int i = etapa 1 ; i> = 0 ; i- ) 
                cout << st [i] << '  ' ; 
            cout << endl; 
            
        } 
        return ; 
    } 

    // Não escolha isso Número 
    dfs (u- 1 , etapa, s); 
    
    // escolhe este número 
    vis [u] = true ; 
    st [etapa] = a [u]; 
    dfs (u - 1 , etapa + 1, s + a [u]); 
    vis [u] = falso ; 
    
} 

int main () 
{ 
    cin >> n;
    para ( int i = 0 ; i <n; i ++) cin >> a [i]; 
    cin >> m; 
    dfs (n - 1 , 0 , 0 ); 
    cout << ans << endl;
    retornar  0 ; 
}

  versão dfs + stl

 

#include <bits / stdc ++. h>
 using  namespace std; 
vector < int > ans; // Armazena qual número está selecionado 
int nums [ 30 ];   // Armazena o conjunto inteiro de entrada 
int n, T;
 int cnt; // Total Número de soluções 
void dfs ( int id, int sum) { // id é o índice do número atravessado no momento, sum é a soma dos números selecionados atualmente 
    se (id == - 1 ) { // se a pesquisa estiver concluída 
        se ( sum == T&& ans.size ()> 0 ) { // Se a soma for T e pelo menos um número estiver selecionado 
            para ( intans.size = I () - 1. ; I> = 0 ; i-- ) {   
                COUT << ANS [I] << "  " ; 
            } 
            COUT << endl; 
            CNT ++ ; 
        } 
        return ; 
    } 
    DFS (ID - 1 , sum); // Não escolhe este número 
     
    ans.push_back (nums [id]); // Selecione este número, adicione este número a ans 
    dfs ( id- 1 , sum + nums [id]); // dfs próxima camada 
    ans.pop_back (); // backtrack 
    
} 
intmain () { 
    cin >> n;
     para ( int i = 0 ; i <n; i ++ ) { 
        cin >> nums [i]; 
    } 
    cin >> T; 
    dfs (n - 1 , 0 ); // do final Um número começa a pesquisar forward 
    cout << cnt << endl;
     return  0 ; 
}

 

A enumeração binária também controla a seleção e a não seleção

Subconjunto de enumeração binária:

  Existem apenas duas possibilidades para cada bit binário, um é 0 e o outro é 1. Consideramos 0 como não selecionando esse número e 1 como selecionando esse número.

  10011 é selecionar o primeiro, quarto e quinto dígitos e os dígitos restantes não são selecionados.

for ( int i =   0 ; i <( 1   << n); i ++);

  Podemos obter todas as situações por esse loop for

  O próximo passo é julgar o número em cada posição (usando a operação AND bit a bit &)

 

Regras de operação AND bit a bit: 0 & 0 = 0 ;   0 & 1 = 0 ;    1 & 0 = 0 ;     1 & 1 = 1 ; 

deslocamento para a esquerda <<< : 

1 << 0 = 1 ( 1 ); 

1 << 1 = 2 ( 10 ); 

1 << 2 = 4 ( 100 ); 

1 << 3 = 8 ( 1000); 

1 << 4 = 16 ( 10000 ); 

... 

1 << 7 = 128 ( 10000000 ); 

...

Podemos executar a operação AND bit a bit deslocando o número binário correspondente a cada caso e o número obtido deslocando 1 e números diferentes para a esquerda

Os dígitos obtidos após 10011 e 1 são deslocados para a esquerda por zero são bit a bit e 10011 & 1 O resultado é 1 que o quinto dígito é selecionado, ou seja, o elemento da matriz com o subscrito 0 é selecionado

10011 e 1 são deslocados para a esquerda por um dígito, e o resultado é bit a bit e 10011 & 100 O resultado é 1 que o quarto dígito é selecionado, ou seja, o elemento da matriz com o subscrito 1 é selecionado

10011 e 1 são deslocados à esquerda por dois dígitos para executar os bits AND 10011 e 100 O resultado é 0, ou seja, o terceiro dígito não está selecionado, ou seja, o elemento da matriz com o subscrito 2 não está selecionado

10011 e 1 são deslocados à esquerda por três dígitos para executar os bits AND 10011 e 1000 O resultado é 0, ou seja, o segundo dígito não está selecionado, ou seja, o elemento da matriz com o índice 3 não está selecionado

10011 e 1 são deslocados para a esquerda por quatro dígitos para executar os resultados AND bit a bit 10011 e 10000 em 1, o primeiro dígito é selecionado, ou seja, o elemento da matriz com o subscrito 4 é selecionado

Adicione os números selecionados para ver se são iguais ao número exigido pela entrada.Se eles são iguais, o resultado é gerado e o número do resultado é aumentado em um.

Execute esta operação em cada caso para obter todos os resultados.

 

#include <iostream> 
#include <cstdio> 
#include <algorithm> 
#include <stack> 
#include <cstring> 
#include <iomanip> 
#include <cmath> usando o namespace std; const int N = 25 ; int n, m, ans;
int a [N], st [N];
bool vis [N]; int main () 
{ 
    cin >> n;
    para ( int i = 0 ; i <n; i ++) cin >> a [i]; 
    cin >>

 

 



for ( int i = 0 ; i <( 1 << n); i ++) // De 0 a 2 ^ n-1 estados 
    {
         int num = 0 ;
         for ( int j = 0 ; j <n; j ++) // Percorre todos os bits do binário 
            if (i >> j & 1 ) // Determina se o j-ésimo bit do binário existe 
                num + = a [j]; // Se houver uma saída, o j-ésimo elemento 
        if (num = = m && i! = 0 ) // Não há caso não selecionado, então i! = 0 
        {
             for ( int j = 0; j <n; j ++ )
                 if (i >> j & 1 ) 
                    cout << a [j] << '  ' ; 
            cout << endl; 
            ans ++ ; 
        } 
    } 
    Cout << ans << endl;
    retornar  0 ; 
}

 

 

 

Acho que você gosta

Origin www.cnblogs.com/zbx2000/p/12757455.html
Recomendado
Clasificación