-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
241 additions
and
0 deletions.
There are no files selected for viewing
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Backtracking | ||
El backtracking es una técnica de resolución de problemas que consiste en generar todas las soluciones posibles que podría tener un problema e ir eliminando aquellas que cominecen a generar resultados que no resuelven el problema. | ||
|
||
Se distingue de la Recursividad, ya que esta busca generar absolutamente todos los resultados aunque no lleguen a una solución. De esta forma se optimiza el tiempo y evitamos el uso de memoria y procesamiento innecesario. | ||
|
||
Ejemplo: Encontrar todas las soluciones posibles para el siguiente sudoku: | ||
|
||
 | ||
|
||
En general, la complejidad temporal de los algoritmos de este tipo llegan a ser exponenciales o incluso factoriales. Sin embargo, esta se reduce gracias a la eliminación de ramas innecesarias. | ||
|
||
 | ||
|
||
## Problemas | ||
- [Good Morning](https://vjudge.net/problem/Kattis-goodmorning) | ||
- [Solución](GoodMorning.cpp) | ||
- [Geppetto](https://vjudge.net/problem/Kattis-geppetto) | ||
- [Solución](Geppetto.cpp) | ||
## Referencias | ||
- [Recursion and Backtracking](https://www.hackerearth.com/practice/basic-programming/recursion/recursion-and-backtracking/tutorial/) | ||
- [A tree-based introduction to backtracking](https://medium.com/swlh/a-tree-based-introduction-to-backtracking-57e38264b2d2) | ||
## Videos | ||
- [6 Introduction to Backtracking - Brute Force Approach](https://www.youtube.com/watch?v=DKCbsiDBN6c) | ||
- [Algorítmia - Tema 5. Backtracking. N-Reinas - Andrés Muñoz Ortega](https://www.youtube.com/watch?v=XQYGwKiqV3Y) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#include <bits/stdc++.h> | ||
#define input freopen("in.txt", "r", stdin) | ||
#define output freopen("out.txt", "w", stdout) | ||
using namespace std; | ||
|
||
// el numero maximo sera 10^18 | ||
// 1000000000000000000 | ||
string number; | ||
int dp[20][2][10]; | ||
|
||
/* | ||
* Digit DP para contar los numeros | ||
* con un 3 o 4 | ||
*/ | ||
int solve_dp(int pos, int mayor,int digito) { | ||
|
||
// Modificar de acuerdo al problema | ||
if(pos == number.size()) { | ||
if(digito == 3 || digito == 4) { | ||
return 1; | ||
} | ||
else { | ||
return 0; | ||
} | ||
} | ||
if(dp[pos][mayor][digito] == -1) { // Pregunto si no lo he calculado | ||
int tope = 9; | ||
if(mayor == true) { | ||
tope = number[pos]-'0'; // solo podemos usar los numeros de 0 al tope | ||
} | ||
dp[pos][mayor][digito] = 0; | ||
for(int i = 0; i <= tope; i++) { | ||
if(i == tope ) { // && mayor | ||
dp[pos][mayor][digito] += solve_dp(pos+1, true, i); | ||
} | ||
else { // 0 1 2 | ||
dp[pos][mayor][digito] += solve_dp(pos+1, false, i); | ||
} | ||
} | ||
} | ||
return dp[pos][mayor][digito]; | ||
} | ||
|
||
|
||
|
||
int main(){ | ||
|
||
// hallar los numeros que tengan 2 pares en su interior del rango 20 hasta 30 | ||
|
||
int a = 99; | ||
int b = 15; | ||
// 152 | ||
// 09 | ||
// calculando f(a) | ||
number = to_string(a); | ||
memset(dp, -1, sizeof(dp)); | ||
int pares_hasta_a = solve_dp(0, true, 0); | ||
// calculando f(b) | ||
memset(dp, -1, sizeof(dp)); | ||
number = to_string(b); | ||
int pares_hasta_b = solve_dp(0, true, 0); | ||
// total para f(a,b) = f(b) - f(a-1) | ||
cout<< pares_hasta_a <<endl; | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#include <bits/stdc++.h> | ||
#define input freopen("in.txt", "r", stdin) | ||
#define output freopen("out.txt", "w", stdout) | ||
using namespace std; | ||
typedef long long ll; | ||
typedef vector<int> vi; | ||
typedef vector<ll> vll; | ||
typedef map<int, int> mii; | ||
|
||
ll _sieve_size; | ||
bitset<10000010> bs; // 10^7 is the rough limit | ||
int v[101]; | ||
vll p; //[2,3,5,7] // compact list of primes | ||
// bs [0,0,1,1,0,1,0,1,....] | ||
void sieve(ll upperbound) { // range = [0..upperbound] | ||
_sieve_size = upperbound+1; // to include upperbound | ||
bs.set(); // all 1s | ||
bs[0] = bs[1] = 0; // except index 0+1 | ||
for (ll i = 2; i < _sieve_size; ++i) if (bs[i]) { | ||
// cross out multiples of i starting from i*i | ||
for (ll j = i*i; j < _sieve_size; j += i) bs[j] = 0; | ||
p.push_back(i); // add prime i to the list | ||
} | ||
} | ||
|
||
// int dp[200000000]; | ||
// void f(vector<int> &v) { | ||
// dp[0] = true; | ||
// for(int i = 0; i < v.size(); i++) { | ||
// for(int j = 0; j<100000000;j++){ | ||
// if(v[i] <= j) { | ||
// dp[j] = dp[j] || dp[j-v[i]]; | ||
// } | ||
// } | ||
// } | ||
// } | ||
|
||
bool isPrime(ll N) { | ||
if (N < _sieve_size) return bs[N]; | ||
for (int i = 0; i < (int)p.size() && p[i]*p[i] <= N; ++i) | ||
if (N%p[i] == 0) | ||
return false; | ||
return true; | ||
} | ||
|
||
vll primeFactors(ll N) { | ||
vll factors; | ||
for (int i = 0; i < (int)p.size() && p[i]*p[i] <= N; ++i){ | ||
while (N%p[i] == 0) { | ||
N /= p[i]; | ||
factors.push_back(p[i]); | ||
} | ||
} | ||
|
||
if (N != 1) factors.push_back(N); | ||
return factors; | ||
} | ||
int dp[100000010]; | ||
int f(int k){ | ||
if(k == 0) return 1; | ||
if( dp[k] == -1) { | ||
int ans = 0; | ||
for(int i = 0; i < k; i++) { | ||
if(k - v[i] >= 0) { | ||
if(k%v[i] == 0) { | ||
dp[k] = 1; | ||
return 1; | ||
} | ||
else { | ||
ans |= f(k-v[i]); | ||
} | ||
} | ||
dp[k] = ans; | ||
} | ||
} | ||
return dp[k]; | ||
} | ||
|
||
int main() { | ||
input; | ||
output; | ||
cout<<1000<<endl; | ||
for(int i = 0; i <1000; i++) { | ||
cout << i+4000<<" "; | ||
} | ||
cout<<endl; | ||
cout<<10000<<endl; | ||
for(int i = 0;i<10000;i++) { | ||
// random number from 1 to 100000000 | ||
int r = rand()%100000000+1; | ||
cout << r<<" "; | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
#include <bits/stdc++.h> | ||
#define input freopen("in.txt", "r", stdin) | ||
#define output freopen("out.txt", "w", stdout) | ||
using namespace std; | ||
|
||
int dp[101][1000000]; | ||
int v[101]; | ||
bool solve(int index, int k) { | ||
if(index == -1) { | ||
if(k == 0){ | ||
return true; | ||
} | ||
return false; | ||
} | ||
if(dp[index][k] == -1) { | ||
if(k-v[index]>=0) { | ||
dp[index][k] = solve(index-1, k-v[index]) || solve(index-1,k); | ||
}else { | ||
dp[index][k] = solve(index-1,k); | ||
} | ||
} | ||
return dp[index][k]; | ||
} | ||
/* | ||
20 7 1 6 9 | ||
0 1 2 3 4 | ||
solve(4,22) | ||
solve(3,13) | ||
solve(2,7) | ||
solve(1,6) | ||
solve(0,6) | ||
solve(1,7) | ||
solve(2,13) | ||
solve(3,22) | ||
*/ | ||
|
||
int main() { | ||
|
||
//input; | ||
int n; | ||
cin >> n; | ||
memset(dp, -1, sizeof(dp)); | ||
for(int i=0; i<n; i++) { | ||
cin>>v[i]; | ||
} | ||
int queries; | ||
cin >> queries; | ||
while(queries--) { | ||
int k; | ||
cin >> k; | ||
if(solve(n-1, k)) | ||
cout << "YES\n"; | ||
else | ||
cout << "NO\n"; | ||
} | ||
} |