GastonFontenla

Subset Sum OIA

Oct 16th, 2016
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.45 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3.  
  4. #define INF (1 << 29)
  5.  
  6. using namespace std;
  7.  
  8. int SubsetSum(vector <int> valoresSet, int maxValor)
  9. {
  10.     vector <vector <bool> > T(valoresSet.size()+1, vector <bool> (maxValor+1, false));
  11.  
  12.     T[0][0] = true; ///Porque el valor 0 lo podemos usar sin usar elementos
  13.  
  14.     for(int i=1; i<=valoresSet.size(); i++)
  15.     {
  16.         for(int j=0; j<=maxValor; j++)
  17.         {
  18.             if(j < valoresSet[i-1]) ///A las celdas menores que el valor
  19.                 T[i][j] = T[i-1][j]; ///Tomo la respuesta de arriba
  20.             else
  21.                 T[i][j] = T[i-1][j-valoresSet[i-1]] or T[i-1][j];
  22.             /**
  23.             En la línea que está arriba de este comentario,
  24.             lo que pregunto es: Puedo formar el valor j
  25.             usando la moneda, o sin usarla? Si es posible
  26.             de alguna de las dos formas, entonces la respuesta
  27.             es true, porque al menos hay una forma de componer ese valor
  28.             **/
  29.         }
  30.     }
  31.  
  32.     /**
  33.     Una vez que calculamos todo, tenemos que verificar si hay respuesta.
  34.     Es posible que algunos valores no se puedan formar.
  35.     Por ejemplo, en este caso no puedo armar el valor 1000.
  36.     En caso de no poder armarse, devuelvo false y listo
  37.     **/
  38.  
  39.     if(T[valoresSet.size()][maxValor] == false)
  40.         return false;
  41.  
  42.     /**
  43.     Si llegué hasta acá es porque hay un set cuya suma es maxValor.
  44.     Ahora hago el backtracking para saber qué valores utilicé
  45.     La idea es empezar de la celda que está mas abajo a la derecha, esa
  46.     es nuestra celda actual.
  47.     Si la celda de arriba también, entonces subo una posición
  48.     Si la celda de arriba es false, entonces
  49.     tengo que subir una posición y además moverme valoresSet[i-1]
  50.     posiciones para la izquierda. En este caso, valoresSet[i-1] es
  51.     parte de la respuesta. Repetir hasta llegar a i = 0
  52.     **/
  53.  
  54.     int i = valoresSet.size();
  55.     int j = maxValor;
  56.  
  57.     cout << "Los elementos que suman " << maxValor << " son: ";
  58.     while(i)///O sea, mientras i > 0
  59.     {
  60.         if(T[i-1][j] == false)
  61.         {
  62.             j -= valoresSet[i-1];
  63.             cout << valoresSet[i-1] << " + ";
  64.         }
  65.         i--; ///Al fin y al cabo, siempre me termino moviendo para arriba
  66.     }
  67.     cout << endl;
  68.  
  69.     return T[valoresSet.size()][maxValor]; ///La última celda tiene la respuesta
  70. }
  71.  
  72. int main()
  73. {
  74.     cout << SubsetSum({7, 2, 3, 6}, 13) << endl;
  75.     return 0;
  76. }
Advertisement
Add Comment
Please, Sign In to add comment