Cod sursa(job #1668612)

Utilizator lflorin29Florin Laiu lflorin29 Data 29 martie 2016 21:53:39
Problema Lapte Scor 90
Compilator cpp Status done
Runda smknretribution Marime 2.18 kb
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define mp make_pair
using namespace std;

int N,L,A[109],B[109],bst[109][109],un[109][109],tmax;
pair<int, int>tata[109][109], ans[109][109];

void Read()
{
  freopen("lapte.in", "r", stdin);
  scanf("%d%d", &N, &L);
  for(int i = 0; i < N; ++i)
    scanf("%d%d",A+i,B+i);
}

int ok(int mij)
{
  memset(bst, 0, sizeof bst);
  for(int i=0;i<=100;++i)for(int j=0;j<=100;++j)tata[i][j]=make_pair(0,0),un[i][j]=-1;
  for(int i = 0; i <= L and A[0] * i <= mij; ++i)
     for(int j = 0; j <= L and A[0] * i + B[0] * j <= mij; ++j)
        bst[0][i] = j, tata[0][i]=make_pair(i,j),un[0][i]=1;
  for(int i = 0; i < N - 1; ++i) {
      for(int uz = 0;uz*A[i+1]<=mij&&uz<=L;++uz)
      {
        int canUse = (mij - A[i + 1] * uz) / B[i + 1];
        bst[i + 1][uz] = canUse;
        tata[i+1][uz]=make_pair(uz,canUse);
        un[i+1][uz]=1;
      }
    for(int j = 0; j <= L; ++j)
    {
      if(un[i][j]==-1)continue;
      for(int fol = 0; fol + j <= L && fol * A[i + 1] <= mij; ++fol) {
        assert(B[i+1]);
         int canUse = (mij - A[i + 1] * fol) / B[i + 1];
         un[i+1][j+fol]=1;
         assert(canUse * B[i + 1] + fol * A[i + 1]<= mij);
         if(bst[i][j] + canUse > bst[i + 1][j + fol])
         {
           bst[i + 1][j+fol] = bst[i][j] + canUse;
           tata[i+1][j+fol]=mp(fol,canUse);
         }
    }
  }
  }

  return bst[N - 1][L] >= L ? 1 : -1;
}

void Reconst(int i, int j, int k)
{
  assert(A[i] * ans[i][j].first + B[i] * ans[i][j].second <= tmax);
  if(i==0){
    printf("%d %d\n", ans[i][j].first,ans[i][j].second);return;
  }
  Reconst(i-1,j-ans[i][j].first,k-ans[i][j].second);
  printf("%d %d\n", ans[i][j].first,ans[i][j].second);
}
void Solve()
{
  int st = 0, dr = 100, res = 0;
  while(st<=dr)
  {
    int m = (st+dr)>>1;
    int z = ok(m);
    if(z!=-1)
    {
      res = m;
      dr = m - 1;tmax=m;
      for(int i=0;i<=100;++i)for(int j=0;j<=100;++j)ans[i][j]=tata[i][j];
    }
    else st= m+1;
  }
  freopen("lapte.out", "w", stdout);
  printf("%d\n", res);
  Reconst(N-1,L,L);
}

int main()
{
  Read();
  Solve();
}