Cod sursa(job #2847812)

Utilizator vladth11Vlad Haivas vladth11 Data 11 februarie 2022 15:36:29
Problema Ghiozdan Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.15 kb
#include <bits/stdc++.h>
#define debug(x) cerr << #x << " " << x << "\n"
#define debugs(x) cerr << #x << " " << x << " "

using namespace std;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <long double, pii> muchie;

const ll NMAX = 75001;
const ll VMAX = 1001;
const ll INF = (1LL << 60);
const ll MOD = 1000000007;
const ll BLOCK = 447;
const ll base = 31;
const ll nr_of_bits = 21;

int f[NMAX];
deque <pii> dq[201];
int dp[NMAX];
pii last[NMAX];
int v[NMAX];

int main() {
    ifstream cin("ghiozdan.in");
    ofstream cout("ghiozdan.out");
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, g, i;
    cin >> n >> g;
    for(i = 1; i <= n; i++) {
        int x;
        cin >> x;
        v[i] = x;
        f[x]++;
    }
    dp[0] = 0;
    for(i = 1; i <= g; i++)
        dp[i] = 1e9;
    for(int i = 1; i < NMAX; i++) {
        if(!f[i])
            continue;
        for(int j = 0; j < i; j++)
            dq[j].clear();
        int cate = f[i];
        for(int j = 0; j <= g; j++) {
            int rest = j % i;
            while(dq[rest].size() && dq[rest].back().first >= dp[j])
                dq[rest].pop_back();
            dq[rest].push_back({dp[j], j});

            while(dq[rest].size() && (j - dq[rest].front().second) > cate * i)
                dq[rest].pop_front();
            int cine = dq[rest].front().second;
            int cat = dq[rest].front().first;
            if(cine + i <= j && cat + (j - cine) / i < dp[j]) {
                dp[j] = cat + (j - cine) / i;
                last[j] = {i, (j - cine) / i};
            }
        }
    }
    for(; g >= 0; g--) {
        if(dp[g] != 1e9)
            break;
    }
    cout << g << " " << dp[g] << "\n";
    int acum = dp[g];
    while(g > 0) { // :( - :)
        for(i = 1; i < NMAX; i++){
            if(g == 0)
                break;
            if(f[i] == 0)
                continue;
            if(i <= g && dp[g - i] == acum - 1) {
                acum--;
                g -= i;
                f[i]--;
                cout << i << "\n";
            }
        }
    }
    return 0;
}