Cod sursa(job #495039)

Utilizator Magnuscont cu nume gresit sau fals Magnus Data 23 octombrie 2010 19:32:55
Problema Lapte Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.48 kb
#include <stdio.h>

int d[101][201],p[101][201],a[101],b[101],i,j,k,s,n,l;

int dp(int sol)
{
    for (i=0;i<=100;++i)
        for (j=0;j<=100;++j)
            d[i][j]=-1;
    d[0][0]=0;
    for (i=1;i<=n;++i)
        for (j=0;j<=l;++j)
            for (k=0;k*a[i]<=sol;++k)
                if ((d[i-1][j]>=0)&&(d[i-1][j]+(sol-k*a[i])/b[i]>d[i][j+k]))
                    d[i][j+k]=d[i-1][j]+(sol-k*a[i])/b[i];
    for (i=l;i<=100;++i) if (d[n][i]>=l) return 1;
    return 0;
}

int bs(int st,int dr)
{
    int mid;
    while (st<dr)
    {
        mid=(st+dr)/2;
        if (dp(mid)<1) st=mid+1;
        else dr=mid;
    }
    mid=(st+dr)/2;
    if (dp(mid)<1) ++mid;
    return mid;
}

void rec(int x,int y)
{
    if (x==0) return;
    rec(x-1,y-p[x][y]);
    printf("%d %d\n",p[x][y],(s-p[x][y]*a[x])/b[x]);
}

int main()
{
    int sol;
    freopen("lapte.in","r",stdin);
    freopen("lapte.out","w",stdout);
    scanf("%d%d",&n,&l);
    for (i=1;i<=n;++i) scanf("%d%d",&a[i],&b[i]);
    sol=bs(1,100);
    s=sol;
    printf("%d\n",sol);
    for (i=0;i<=100;++i)
        for (j=0;j<=100;++j)
            d[i][j]=-1;
    d[0][0]=0;
    for (i=1;i<=n;++i)
        for (j=0;j<=l;++j)
            for (k=0;k*a[i]<=sol;++k)
                if ((d[i-1][j]>=0)&&(d[i-1][j]+(sol-k*a[i])/b[i]>d[i][j+k]))
                    {d[i][j+k]=d[i-1][j]+(sol-k*a[i])/b[i];p[i][j+k]=k;}
    for (i=l;i<=100;++i) if (d[n][i]>=l) break;
    rec(n,i);
    return 0;
}