Cod sursa(job #2847830)

Utilizator vladth11Vlad Haivas vladth11 Data 11 februarie 2022 16:03:05
Problema Ghiozdan Scor 88
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.04 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];
class InParser {
private:
	FILE *fin;
	char *buff;
	int sp;

	char read_ch() {
		++sp;
		if (sp == 4096) {
			sp = 0;
			fread(buff, 1, 4096, fin);
		}
		return buff[sp];
	}

public:
	InParser(const char* nume) {
		fin = fopen(nume, "r");
		buff = new char[4096]();
		sp = 4095;
	}

	InParser& operator >> (int &n) {
		char c;
		while (!isdigit(c = read_ch()) && c != '-');
		int sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		} else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}

	InParser& operator >> (long long &n) {
		char c;
		n = 0;
		while (!isdigit(c = read_ch()) && c != '-');
		long long sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		} else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}
};

int main() {
    InParser cin("ghiozdan.in");
    ofstream cout("ghiozdan.out");
    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 < 201; 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) { // :( - :)
        int init = g;
        for(i = 1; i < 201; 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";
            }
        }
        if(init == g){
            break;
        }
    }
    return 0;
}