Cod sursa(job #811740)

Utilizator tzipleatudTudor Tiplea tzipleatud Data 12 noiembrie 2012 21:32:25
Problema Lapte Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.68 kb
#include <fstream>
#include <cstring>
#define NM 110

using namespace std;

ifstream f("lapte.in");
ofstream g("lapte.out");

int N,L,M;
int ANS;
int i,j,k;
int A[NM],B[NM];
int DP[NM][NM];
int V[NM][NM];
int Sol[NM];
bool P[NM][NM];

bool Check (int T, int O)
{
    memset(DP,0,sizeof(DP));
    memset(V,0,sizeof(V));
    memset(P,0,sizeof(P));
    int MX;
    int PZ;

    for (j=0; j<=T/A[1]; j++)
    {
        DP[1][j]=(T-A[1]*j)/B[1];
        V[1][j]=j;
        P[1][j]=1;
    }

    for (i=2; i<=N; i++)
    {
        for (j=0; j<=L; j++)
        {
            MX=-1;
            PZ=0;
            for (k=0; k<=j && A[i]*k<=T; k++)
                if (DP[i-1][j-k]+(T-A[i]*k)/B[i]>MX && P[i-1][j-k])
                {
                    MX=DP[i-1][j-k]+(T-A[i]*k)/B[i];
                    PZ=k;
                }

            DP[i][j]=MX;
            V[i][j]=PZ;
            if (MX>=0)
                P[i][j]=1;
        }
    }

    if (DP[N][L]>=L && O==0)
        return 1;
    if (O==0)
        return 0;

    k=L;
    for (i=N; i>=1; i--)
    {
        Sol[i]=V[i][k];
        k-=V[i][k];
    }
}

void Solve ()
{
    int P=1,U=NM,M;
    ANS=NM;

    while (P<=U)
    {
        M=(P+U)/2;
        if (Check(M,0))
        {
            ANS=M;
            U=M-1;
        }
        else
            P=M+1;
    }

    return;
}

int main ()
{
    f >> N >> L;
    for (i=1; i<=N; i++)
        f >> A[i] >> B[i];

    Solve();

    g << ANS << '\n';
    Check(ANS,1);

    for (i=1; i<=N; i++)
        g << Sol[i] << ' ' << (ANS-Sol[i]*A[i])/B[i] << '\n';

    f.close();
    g.close();

    return 0;
}