Cod sursa(job #1262829)

Utilizator MarcvsHdrMihai Leonte MarcvsHdr Data 13 noiembrie 2014 16:26:47
Problema Lapte Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.17 kb
#include <iostream>
#include <fstream>

#include <vector>

int n, l;
int ta[101];
int tb[101];
int tata[101][101];
std::pair<int, int> drank[101][101];
std::vector<std::pair<int,
    std::pair<int, int> > > queue(1 + 101 * 101); // (i, (tla, tlb))

bool ok(int t, std::vector<std::pair<int, int> >& sol) {
  int possible[101][101] = { 0 };
  possible[0][0] = true;
  int begin = 0;
  int end = 0;
  queue[0] = std::make_pair(0, std::make_pair(0, 0));
  while (begin <= end && !possible[l][l]) {
    int nexti = queue[begin].first + 1;
    int ctla = queue[begin].second.first;
    int ctlb = queue[begin].second.second;
    begin++;
    if (nexti > n) {
      continue;
    }
    for (int la = 0; la <= t / ta[nexti] && ctla + la <= l; ++la) {
      int lb = std::min(l - ctlb, (t - la * ta[nexti]) / tb[nexti]);
      // Add to the queue, if not already in there.
      if ((la || lb) && !possible[ctla + la][ctlb + lb]) {
        possible[ctla + la][ctlb + lb] = true;
        tata[ctla + la][ctlb + lb] = nexti;
        drank[ctla + la][ctlb + lb] = std::make_pair(la, lb);
        queue[++end] =
            std::make_pair(nexti, std::make_pair(ctla + la, ctlb + lb));
      }
    }
  }

  if (possible[l][l]) {
    int ia = l;
    int ib = l;
    sol.clear();
    sol.resize(n + 1, std::make_pair(0, 0));
    while (ia || ib) {
      int node = tata[ia][ib];
      sol[node] = drank[ia][ib];
      ia -= sol[node].first;
      ib -= sol[node].second;
    }
    return true;
  } else {
    return false;
  }
}

int main()
{
  std::ifstream in("lapte.in");
  std::ofstream out("lapte.out");

  in >> n >> l;
  int stm;
  for (int i = 1; i <= n; ++i) {
    in >> ta[i] >> tb[i];
    if (i == 1) {
      stm = ta[i] + tb[i];
    } else {
      stm = (stm > (ta[i] + tb[i]) ? (ta[i] + tb[i]) : stm);
    }
  }

  int li = 1;
  int lf = l * stm;
  int tsol = lf;
  std::vector<std::pair<int, int> > sol;
  while (li <= lf) {
    int m = (li + lf) / 2;
    if (ok(m, sol)) {
      tsol = m;
      lf = m - 1;
    } else {
      li = m + 1;
    }
  }

  out << tsol << std::endl;
  for (int i = 1; i <= n; ++i) {
    out << sol[i].first << " " << sol[i].second << std::endl;
  }

  in.close();
  out.close();

  return 0;
}