Cod sursa(job #2929359)

Utilizator Theo14Ancuta Theodor Theo14 Data 25 octombrie 2022 18:11:33
Problema Lapte Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.29 kb
#include<bits/stdc++.h>
#define int long long
#define INF 1000000000
using namespace std;

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

int n,l,dp[105][105];///dp[i][LAtotal]= cantitatea maxima de LBtotal care se poate bea daca se poate sa bei LAtotal cu primele i persoane
vector< pair<int,int> >w;
struct elem
{
    int x,y;
} v[105];

int verif(int timp)
{
    int i,LAtotal,la,lb;
    for(i=0; i<=n; i++)
        for(LAtotal=0; LAtotal<=l; LAtotal++)
            dp[i][LAtotal]=-INF;
    dp[0][0]=0;
    for(i=1; i<=n; i++)
    {
        for(LAtotal=0; LAtotal<=l; LAtotal++)
        {
            for(la=0; la<=min(la,timp/v[i].x); la++)
            {
                lb=(timp-la*v[i].x)/v[i].y;
                dp[i][LAtotal] = max(dp[i][LAtotal],dp[i-1][max(1LL*0,LAtotal-la)]+lb);
            }
        }
    }
    if(dp[n][l]>=l)
        return 1;
    return 0;
}

void reconstituire(int timp)
{
    int i,LAtotal,la,lb,j;
    for(i=0; i<=n; i++)
        for(LAtotal=0; LAtotal<=l; LAtotal++)
            dp[i][LAtotal]=-INF;
    dp[0][0]=0;
    for(i=1; i<=n; i++)
    {
        for(LAtotal=0; LAtotal<=l; LAtotal++)
        {
            for(la=0; la<=min(la,timp/v[i].x); la++)
            {
                lb=(timp-la*v[i].x)/v[i].y;
                dp[i][LAtotal] = max(dp[i][LAtotal],dp[i-1][max(1LL*0,LAtotal-la)]+lb);
            }
        }
    }
    i=n;
    j=l;
    int ans1,ans2,k;
    while(i>=1)
    {
        for(la=0;la<=min(la,timp/v[i].x);la++)
        {
            lb=(timp-la*v[i].x)/v[i].y;
            if(j-la>=0 && dp[i-1][j-la]+lb==dp[i][j])
            {
                ans1=la;
                ans2=lb;
                k=la;
            }
        }
        w.push_back({ans1,ans2});
        i--;
        j-=k;
    }
    reverse(w.begin(),w.end());
    for(auto it:w)
        g<<it.first<<" "<<it.second<<'\n';
}

signed main()
{
    int i,st,dr,retin;
    f>>n>>l;
    for(i=1; i<=n; i++)
        f>>v[i].x>>v[i].y;
    st=1;
    dr=100;
    while(st<=dr)
    {
        int mij=(st+dr)/2;
        if(verif(mij))
        {
            retin=mij;
            dr=mij-1;
        }
        else
            st=mij+1;
    }
    g<<retin<<'\n';
    //RECONSTITUIRE
    reconstituire(retin);
    return 0;
}