Cod sursa(job #2519322)

Utilizator flaviu_2001Craciun Ioan-Flaviu flaviu_2001 Data 7 ianuarie 2020 16:20:56
Problema Lapte Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.18 kb
#include <bits/stdc++.h>
#define ff first
#define ss second

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pi;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;

const string file = "lapte";
const ll INF = 9223372036854775807ll;
const int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1}, inf = 2147483647, nmax = 105;

struct trip{
    int a, b, c;
};

int n, M, free2[nmax], use[nmax], pd[nmax][nmax];
trip sol[nmax][nmax];
pi p[nmax];

int get_loss(int i, int j, int mid)
{
    return use[i] - ((mid-j*p[i].ss)/p[i].ff);
}

bool check(int mid)
{
    int all = 0;
    for (int i = 1; i <= n; ++i){
        use[i] = mid/p[i].ff;
        free2[i] = mid-use[i]*p[i].ff;
        all += use[i];
    }
    memset(pd, 0, sizeof(pd));
    pd[0][0] = all;
    for (int i = 1; i <= n; ++i){
        for (int put_right = 0; put_right <= M; ++put_right){
            pd[i][put_right] = pd[i-1][put_right];
            sol[i][put_right] = {put_right, use[i], 0};
            for (int j = 1; 1; ++j){
                if (j*p[i].ss > mid)
                    break;
                if (pd[i][put_right] < pd[i-1][put_right-j]-get_loss(i, j, mid)){
                    pd[i][put_right] = pd[i-1][put_right-j]-get_loss(i, j, mid);
                    sol[i][put_right] = {put_right-j, (mid-j*p[i].ss)/p[i].ff, j};
                }
                pd[i][put_right] = max(pd[i][put_right], pd[i-1][put_right-j]-get_loss(i, j, mid));
            }
        }
    }
    return pd[n][M] >= M;
}

int main()
{
    ifstream fin (file+".in");
    ofstream fout (file+".out");
    fin >> n >> M;
    for (int i = 1; i <= n; ++i)
        fin >> p[i].ff >> p[i].ss;
    int lo = 0, hi = nmax, mid, ans=nmax;
    for (mid = (lo+hi)/2; lo <= hi; mid = (lo+hi)/2)
        if (check(mid)){
            ans = mid;
            hi = mid-1;
        }else lo = mid+1;
    check(ans);
    fout << ans << "\n";
    vector<pi> show;
    int now1 = n, now2 = M;
    while(now1 > 0){
        show.push_back({sol[now1][now2].b, sol[now1][now2].c});
        now2 = sol[now1][now2].a;
        --now1;
    }
    reverse(show.begin(), show.end());
    for (auto x : show)
        fout << x.ff << " " << x.ss << "\n";
    return 0;
}