Cod sursa(job #944017)

Utilizator PetcuIoanPetcu Ioan Vlad PetcuIoan Data 27 aprilie 2013 09:57:40
Problema Lapte Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.01 kb
#include<cstring>
#include<fstream>

using namespace std;

int n, lm, len, xi, xj, xk, capa[105], capb[105], usea[105], useb[105], dp[105][155][155];

void go_dp(int mid){
  memset(dp, 0, sizeof(dp));

    int q, r;
    dp[0][0][0] = 1;
    for(int i = 1; i <= n; ++i)
      for(int j = 1; j <= lm; ++j)
        for(int k = 1; k <= lm; ++k){
          q = mid / capa[i];
          for(int l = 0; l <= q; ++l){
            r = (mid - l * capa[i]) / capb[i];
            if(l <= j && r <= k)
              dp[i][j][k] |= dp[i - 1][j - l][k - r];
          }
          if(dp[i][j][k] && j >= len && k >= len){
            xi = i;
            xj = j;
            xk = k;
            return;
          }
        }
}

void get_ans(int x){
  go_dp(x);

  int q, r;
  while(xi != 0){
    q = x / capa[xi];
    for(int i = 0; i <= q; ++i){
      r = (x - i * capa[xi]) / capb[xi];
      if(dp[xi - 1][xj - i][xk - r]){
        usea[xi] = i;
        useb[xi] = r;
        --xi;
        xj -= i;
        xk -= r;
        break;
      }
    }
  }
}

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

  in >> n >> len;
  lm = len + 10;

  for(int i = 1; i <= n; ++i)
    in >> capa[i] >> capb[i];

  int left = 1, right = 100, mid, last = -1;

  while(left <= right){
    mid = (left + right) >> 1;

    memset(dp, 0, sizeof(dp));

    int q, r, ok = 0;
    dp[0][0][0] = 1;
    for(int i = 1; i <= n; ++i)
      for(int j = 1; j <= lm; ++j)
        for(int k = 1; k <= lm; ++k){
          q = mid / capa[i];
          for(int l = 0; l <= q; ++l){
            r = (mid - l * capa[i]) / capb[i];
            if(l <= j && r <= k)
              dp[i][j][k] |= dp[i - 1][j - l][k - r];
          }
          if(dp[i][j][k] && j >= len && k >= len){
            ok = 1;
            goto salvation;
          }
        }
salvation: ;

    if(ok){
      last = mid;
      right = mid - 1;
    }
    else
      left = mid + 1;
  }

  get_ans(last);

  out << last << "\n";
  for(int i = 1; i <= n; ++i)
    out << usea[i] << " " << useb[i] << "\n";

  return 0;
}