Cod sursa(job #1205356)

Utilizator ZenusTudor Costin Razvan Zenus Data 6 iulie 2014 11:53:25
Problema Lapte Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.43 kb
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <climits>

using namespace std;

#define NMAX 150
#define PII pair < int , int >

int D[NMAX][NMAX],P[NMAX][NMAX];
PII L[NMAX],final[NMAX];
int N,M,mid,left,right,i;

bool Drink(int tme)
{
    memset(P,0,sizeof(P));
    memset(D,0,sizeof(D));
    int i,j,k;

    for (i=0;i<=N;++i)
    for (j=1;j<=M;++j)
    D[i][j]=-INT_MAX;

    for (i=1;i<=N;++i)
    for (j=0;j<=M;++j)
    for (k=0;k<=min(tme/L[i].first,j);++k)
    {
        if (D[i-1][j-k]==-INT_MAX) continue;
        if (D[i][j]>=D[i-1][j-k]+(tme-k*L[i].first)/L[i].second) continue;

        D[i][j]=D[i-1][j-k]+(tme-k*L[i].first)/L[i].second;
        P[i][j]=k;
    }

    if (D[N][M]>=M) return true;
    return false;
}

int main()
{
freopen("lapte.in","r",stdin);
freopen("lapte.out","w",stdout);

scanf("%d%d",&N,&M);

for (i=1;i<=N;++i)
scanf("%d%d",&L[i].first,&L[i].second);

left=0,right=M*(L[1].first+L[1].second);

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

    if (Drink(mid))
    {
        final[0].first=mid;
        right=mid-1;
        continue;
    }
    left=mid+1;
}

for (i=N;i>=1;--i)
{
    final[i].first=P[i][M];
    M-=final[i].first;
    final[i].second=(final[0].first-final[i].first*L[i].first)/L[i].second;
}

printf("%d\n",final[0].first);

for (i=1;i<=N;++i)
printf("%d %d\n",final[i].first,final[i].second);

return 0;
}