Cod sursa(job #1189471)

Utilizator andreiagAndrei Galusca andreiag Data 22 mai 2014 21:46:20
Problema Lapte Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.72 kb
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>

using namespace std;
typedef pair<char, char> pcc;
typedef pair<int, pair<int, int>> pipii;
const int Nmax = 105;
const int Lmax = 105;

int N, L;
int B[Nmax][2];
int dp[Lmax];       // global dp
int nt[Lmax];       // next dp
int sol[Nmax][2];
pipii from[Lmax][Lmax];
pipii tmp[Lmax][Lmax];

inline int min(int x, int y) { return x < y ? x : y; }
inline int max(int x, int y) { return x > y ? x : y; }

bool check(int T)
{
    memset(dp, -1, sizeof(dp));
    dp[0] = 0;
    for (int n = 0; n < N; n++)
    {
        int a = B[n][0];
        int b = B[n][1];
        for (int l = 0; l <= L; l++)
            nt[l] = -1;
        int x = 0;
        while(x*a <= T)
        {
            int y = (T - x*a) / b;
            for (int l = 0; l <= L; l++)
                if (dp[l] >= 0)
                {
                    if (l+x <= L && nt[l+x] < L && nt[l+x] < dp[l] + y)
                    {
                        nt[l+x] = dp[l] + y;
                        if (nt[l+x] > L)
                            nt[l+x] = L;
                        tmp[l+x][nt[l+x]] = make_pair(n, make_pair(l, dp[l]));
                    }
                    else if (l+x > L && nt[L] < L && nt[L] < dp[l] + y)
                    {
                        nt[L] = dp[l] + y;
                        if (nt[L] > L)
                            nt[L] = L;
                        tmp[L][nt[L]] = make_pair(n, make_pair(l, dp[l]));
                    }
                }
            x++;
            //x = max(x+1, (T - (y-1)*b)/a);
        }
        
        for (int l = 0; l <= L; l++)
            if (dp[l] < nt[l])
            {
                dp[l] = nt[l];
                from[l][nt[l]] = tmp[l][nt[l]];
            }
        if (dp[L] >= L)
        {
            memset(sol, 0, sizeof(sol));
            int x = L, y = L;
            while(x > 0 || y > 0)
            {
                int person = from[x][y].first;
                int prev_x = from[x][y].second.first;
                int prev_y = from[x][y].second.second;
                sol[person][0] += x - prev_x;
                sol[person][1] += y - prev_y;
                x = prev_x;
                y = prev_y;
            }
            return 1;
        }
    }
    return 0;
}

int main()
{
    ifstream f ("lapte.in");
    ofstream g ("lapte.out");
    
    f >> N >> L;
    for (int n = 0; n < N; n++)
        f >> B[n][0] >> B[n][1];
    
    int low = 1, high = 205*L;
    while(low < high)
    {
        int mid = (high +low)/2;
        if (check(mid))
            high = mid;
        else
            low = mid +1;
    }
    g << low << '\n';
    for (int n = 0; n < N; n++)
        g << sol[n][0] << ' ' << sol[n][1] << '\n';

    return 0;
}