N inteiros na segunda linha, separados por espaços.
Um número inteiro T na terceira linha indica a soma a ser alcançada.
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.
-7 -3 -2 5 9
0
-7 -2 9
2
T <= maxlongint A soma
de qualquer elemento do conjunto não excede o intervalo de comprimento
#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 ; }