Cod sursa(job #513460)

Utilizator freak93Adrian Budau freak93 Data 15 decembrie 2010 21:49:57
Problema Ghiozdan Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.6 kb
#include <fstream>

using namespace std;

const char iname[] = "ghiozdan.in";
const char oname[] = "ghiozdan.out";
const int maxg = 75005;
const int maxv = 205;

ifstream f(iname);
ofstream g(oname);

int deque[maxg], v[maxv], aux[maxg], dp[2][maxg];

void dynamic(int x, int y, int G, int *dp) {
	memset(dp, -1, sizeof(int) * (G + 1));
	dp[0] = 0;
	for (int i = x; i < y; ++i) 
		for (int j = 0; j < i; ++j) {
			int p = 1, q = 0;
			if (dp[j] != -1)
				deque[++q] = j;
			for (int k = i + j; k <= G; k += i) {
            	while (p <= q && deque[p] < k - v[i] * i && p <= q)
					++p;
				if (p <= q)
					aux[k] = dp[deque[p]] + (k - deque[p]) / i;
				else
					aux[k] = -1;
                if (dp[k] == -1)
					continue;
				while (q >= p && dp[deque[q]] + (k - deque[q]) / i >= dp[k])
					--q;
				deque[++q] = k;
			}
			for (int k = i +j; k <= G; k += i)
				if ((dp[k] == -1 || dp[k] > aux[k]) && aux[k] != -1)
					dp[k] = aux[k];
		}
}

void solve(int x, int y, int G, int answer) {
	if (G == 0)
		return;
	if (x == y - 1) {
		for (int i = 1; i <= G / x; ++i)
			g << x << "\n";
		return;
	}
	int mid = (x + y) / 2;
	dynamic(x, mid, G, dp[0]);
	dynamic(mid, y, G, dp[1]);
	for (int i = 0; i <= G; ++i)
		if (dp[0][i] != - 1 && dp[1][G - i] != -1 && dp[0][i] + dp[1][G - i] == answer) {
			int p = dp[0][i], q = dp[1][G - i];
			solve(x, mid, i, p);
			solve(mid, y, G - i, q);
			return;
		}
}

int n, G, i, x;

int main() {
	f >> n >> G;

	for (i = 0; i < n; ++i)
		f >> x, ++v[x];

	dynamic(1, 201, G, dp[0]);
	for (i = G; i >= 0 && dp[0][i] == -1; --i);
	g << i << " " << dp[0][i] << "\n";
	solve(1, 201, i, dp[0][i]);
}