Cod sursa(job #1028717)

Utilizator juniorOvidiu Rosca junior Data 14 noiembrie 2013 16:45:30
Problema Energii Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.09 kb
/* ? p pe infoarena */

#include <fstream>
#include <iostream>
#include <iomanip>
#include <cstring>

#define MAXE 33
#define INFINIT 1000000000
//#define DEBUG

using namespace std;

struct generator {
  int e, c;
};

generator g[5001];
int G, W, l, cs, e, cn, minim, lp[10001], lc[10001];
ifstream fi ("energii.in");
ofstream fo ("energii.out");

/* Ideea de rezolvare:
   Pentru un rucsac de capacitate e, asociem obiectul curent (l), avand greutatea g[l].e,
   cu varianta optima obtinuta prin plasarea g l-1 obiecte intr-un rucsac cu capacitate e-g[l].e.

   Pentru o cantitate de energie w, asociem generatorul curent (l), care produce e[l].e energie,
   cu varianta optima obtinuta prin utilizarea g l-1 generatoare pentru g obtine w-e[l].e energie.
   */

int main() {
  fi >> G >> W;
  for (l = 1; l <= G; l++)
    fi >> g[l].e >> g[l].c;
  //lp = 0; lc = 1;
  for (e = 1; e <= MAXE; e++)
    lp[e] = lc[e] = INFINIT; // Inca nu exista o varianta pentru a obtine energia e. !!
  for (l = 1; l <= G; l++) { // pentru fiecare generator (cu rol de linie)
    for (e = 0; e <= MAXE; e++) { // pentru fiecare cantitate de energie care se va analiza (cu rol de coloana)
      cs = e - g[l].e; // coloana din stanga, care se combina cu energia generatorului curent
      if (cs >= 0)
        if (lp[cs] < INFINIT) { // Exista o varianta pentru a obtine energia cs.
          cn = lp[cs] + g[l].c; // costul nou, obtinut folosind generatorul l
          if (cn < lp[e]) {           // Avem cost mai mic folosind generatorul curent?
            lc[e] = cn;              // Retinem costul nou.
          }
          else
            lc[e] = lp[e]; // Retinem costul obtinut cu primele l-1 generatoare.
        }
    }
    memcpy(lp, lc, sizeof(lc));
    //lp = 1 - lp; lc = 1 - lc;
  }
#ifdef DEBUG
  for (e = 1; e <= 33; e++)
    if (lp[e] < INFINIT)
      cout << '[' << setw(2) << e << ',' << lp[e] << "] ";
    else
      cout << ". ";
#endif
  minim = INFINIT;
  for (e = W; e <= MAXE; e++) // !!
    if (lp[e] < minim)
      minim = lp[e];
  fo << minim;
  return 0;
}