Cod sursa(job #1261890)

Utilizator MarcvsHdrMihai Leonte MarcvsHdr Data 12 noiembrie 2014 20:05:40
Problema Lapte Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.8 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];

bool ok(int to_drink, int t, std::vector<std::pair<int, int> >& sol) {
  int possible[101][101] = { 0 };
  possible[0][0] = true;
  for (int i = 1; i <= n; ++i) {
    for (int tla = to_drink; tla >= 0; --tla) {
      for (int tlb = to_drink; tlb >= 0; --tlb) {
        for (int la = 0; la <= t / ta[i] && la <= tla; ++la) {
          int lb = std::min(tlb, (t - la * ta[i]) / tb[i]);
          if ((la || lb) && possible[tla - la][tlb - lb] && !possible[tla][tlb]) {
            possible[tla][tlb] = true;
            tata[tla][tlb] = i;
            drank[tla][tlb] = std::make_pair(la, lb);
          }
        }
      }
    }
  }

  if (possible[to_drink][to_drink]) {
    int ia = to_drink;
    int ib = to_drink;
    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(l, 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;
}