Cod sursa(job #1200442)

Utilizator teoionescuIonescu Teodor teoionescu Data 22 iunie 2014 14:58:57
Problema Lapte Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.23 kb
#include<fstream>
#define abs(x) ((x>0)?(x):(-(x)))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
ifstream in("lapte.in");
ofstream out("lapte.out");
const int Nmax = 101;
int A[Nmax],B[Nmax];
int N,L;
int G[21000];
int U[Nmax],R[Nmax],SU,E;
int ok(int S){
    int a=0,b=0;
    for(int i=1;i<=N;i++){
        a+=(S/2)/A[i];
        b+=(S/2)/B[i];
        if(a>=L && b>=L) return 1;
    }
    for(int i=0;i<=20100;i++) G[i]=-1;
    SU=G[0]=0;
    for(int i=1;i<=N;i++) U[i]=S/A[i] , R[i]=S-A[i]*U[i] , SU+=U[i];
    E=SU-L;
    for(int i=1;i<=N;i++){
        for(int j=E;j>=0;j--) if(G[j]!=-1){
            for(int k=1;k<=min(E,U[i]);k++){
                int add=(A[i]*k+R[i])/B[i];
                if( j+k<=E && (G[j+k]==-1 || G[j+k]<G[j]+add) ) G[j+k]=G[j]+add;
            }
        }
    }
    for(int i=1;i<=E;i++) if(G[i]>=L) return 1;
    return 0;
}
int K[Nmax][21000],T[Nmax][21000];
int LT[21000];
int a[Nmax],b[Nmax];
void reconst(int S){
    for(int i=0;i<=20100;i++) G[i]=-1;
    SU=G[0]=0;
    for(int i=1;i<=N;i++) U[i]=S/A[i] , R[i]=S-A[i]*U[i] , SU+=U[i];
    E=SU-L;
    for(int i=1;i<=N;i++){
        for(int j=E;j>=0;j--) if(G[j]!=-1){
            for(int k=1;k<=min(E,U[i]);k++){
                int add=(A[i]*k+R[i])/B[i];
                if( j+k<=E && (G[j+k]==-1 || G[j+k]<G[j]+add) ){
                    G[j+k]=G[j]+add;
                    K[i][j+k]=k;
                    T[i][j+k]=LT[j];
                    LT[j+k]=i;
                }
            }
        }
    }
    for(int i=1;i<=E;i++) if(G[i]>=L){
        for(int i=1;i<=N;i++) a[i]=U[i],b[i]=0;
        int lev=LT[i],pos=i;
        while(pos){
            int t=(A[lev]*K[lev][pos]+R[lev])/B[lev];
            a[lev]-=K[lev][pos];
            b[lev]+=t;
            int aux=pos-K[lev][pos];
            lev=T[lev][pos];
            pos=aux;
        }
        for(int i=1;i<=N;i++) out<<a[i]<<' '<<b[i]<<'\n';
        return;
    }
}
int main(){
    in>>N>>L;
    for(int i=1;i<=N;i++) in>>A[i]>>B[i];
    int i=0,pas=(1<<15);
    while(pas){
        if(!ok(i+pas)) i+=pas;
        pas>>=1;
    }
    int ans=i+1;
    out<<ans<<'\n';
    reconst(ans);
    return 0;
}