Skip to content

Commit

Permalink
Backtracking completo
Browse files Browse the repository at this point in the history
  • Loading branch information
eavm314 committed Oct 30, 2022
1 parent a997479 commit 4f5ac32
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 0 deletions.
File renamed without changes.
File renamed without changes.
24 changes: 24 additions & 0 deletions Backtracking/README.md
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:

![Sudoku](https://www.researchgate.net/profile/Radek-Pelanek/publication/261217550/figure/fig4/AS:667715102593028@1536207094075/Comprised-version-of-a-search-tree-of-a-backtracking-algorithm-on-a-4-4-Sudoku-puzzle.ppm)

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.

![BT](https://www.tutorialspoint.com/prolog/images/backtracking.jpg)

## 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)
65 changes: 65 additions & 0 deletions ProgramacionDinamica/DigitDP/DigitDP.cpp
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;
}
94 changes: 94 additions & 0 deletions ProgramacionDinamica/SubsetSum/SubsetSumBU.cpp
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;
}
58 changes: 58 additions & 0 deletions ProgramacionDinamica/SubsetSum/SubsetSumTD.cpp
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";
}
}

0 comments on commit 4f5ac32

Please sign in to comment.