Cod sursa(job #420382)

Utilizator vladiiIonescu Vlad vladii Data 18 martie 2010 22:08:42
Problema Lapte Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.49 kb
#include <iostream>
using namespace std;

int N, L;
int A[101], B[101], La[101], Lb[101];
int P[101][101], M[101][101];

/**
int Verifica(int timp) {
    int i, j, p, q;
    for(i=1; i<=N; i++) {
         for(j=0; j<=101; j++) {
              M[i][j]=0;
         }
    }
    for(i=0; i<=N; i++) {
         for(j=0; j<=L; j++) {
              M[i][j]=-99999999;
         }
    }
    M[0][0]=0;
    for(i=1; i<=N; i++) {
         for(j=0; j<=L; j++) {
              for(p=0; p<j; p++) {
                   q=-9999999;
                   if(p*A[i]<=timp) {
                        q=M[i-1][j-p]+(timp-p*A[i])/B[i];
                   }
                   M[i][j]=max(M[i][j], q);
              }
         }
    }
    if(M[N][L]>=L) { return 1; }
    return 0;
}
**/

int Verifica (int T) {
	
	int i, j, l, b;
	for (i = 1; i <= N; i++)
		memset (M[i], 0, sizeof (M[i]));
	
	for (i = 0; i <= N; i++)
		for (j = 0; j <= L; j++) {
			M[i][j] = -99999999;
		}
        	
	M[0][0] = 0;
	for (i = 1; i <= N; i++)
		for (j = 0; j <= L; j++)  
			for (l = 0; l <= j; l++) {
				b = M[i-1][j - l];
				
				if ( l * A[i] <= T ) 
					b+= (T - (l * A[i])) / B[i];
				else
					b = -99999999;
                    		
				if (M[i][j] < b) {
					M[i][j] = b;
				}
			}
	if (M[N][L] >= L) return 1;
	return 0;
} 

int main() {
    FILE *f1=fopen("lapte.in", "r"), *f2=fopen("lapte.out", "w");
    int i, j, p, sol=0, mla, mlb, ok=0;
    fscanf(f1, "%d%d", &N, &L);
    for(i=1; i<=N; i++) {
         fscanf(f1, "%d%d", &A[i], &B[i]);
    }
    int ls=1, ld=102;
    while(ls<=ld) {
         int mij=(ls+ld)/2;
         if(Verifica(mij)) {
              //e posibil, deci caut un timp mai mic
              sol=mij;
              ld=mij-1;
         }
         else {
              //timp mai mare
              ls=mij+1;
         }
    }
    fprintf(f2, "%d\n", sol);
    //reconstituiesc solutia
    int timp=sol;
    for(i=1; i<=N; i++) {
         for(j=0; j<=timp/A[i]; j++) {
              P[i][j]=(timp-j*A[i])/B[i];
         }
    }
    for(i=0; i<=timp/A[1]; i++) {
         M[1][i]=P[1][i];
    }
    for(i=2; i<=N; i++) {
         for(j=0; j<=L; j++) {
              for(p=0; p<=timp/A[i]; p++) {
                   if(p+j>=L) { M[i][p+j]=max(M[i][L], M[i-1][j]+P[i][p]); continue; }
                   M[i][p+j]=max(M[i][p+j], M[i-1][j]+P[i][p]);
              }
         }
    }
    mla=L; mlb=L;
    for(i=N; i>=1; i--) {
         for(j=0; j<=L; j++) {
              for(p=0; p<=timp/A[i]; p++) {
                   if(i==N) {
                        if(j+p>=L && M[i-1][j]+P[i][p]>=L) {
                             //primele i-1 persoane tre sa bea exact (j, M[i-1][j]) litri
                             La[i]=p; Lb[i]=P[i][p];
                             mla=j; mlb=M[i-1][j];
                             ok=1; break;
                        }
                   }
                   else {
                        if(j+p==mla && M[i-1][j]+P[i][p]==mlb) {
                             //primele i-1 persoane tre sa bea exact (j, M[i-1][j]) litri
                             La[i]=p; Lb[i]=P[i][p];
                             mla=j; mlb=M[i-1][j];
                             ok=1; break;
                        }
                   }
              }
              if(ok) { ok=0; break; }
         }
    }
    for(i=1; i<=N; i++) {
         fprintf(f2, "%d %d\n", La[i], Lb[i]);
    }
    fclose(f1); fclose(f2);
    return 0;
}