Cod sursa(job #512533)

Utilizator toni2007Pripoae Teodor Anton toni2007 Data 13 decembrie 2010 23:14:14
Problema Ghiozdan Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.95 kb
#include <stdio.h>
#include <assert.h>
#include <vector>
#include <algorithm>

using namespace std;

#define oo 		1000000
#define maxN 	210
#define maxG 	75100

int N, G, A[2][maxG], deque[maxG], freq[maxN];
vector < pair <short int, short int> > pred[maxG];

void reconstr (int G, int Ind) {
	vector < pair < short int, short int > > :: iterator it;
	if (G == 0)
		return;
	for (it = pred[G].begin(); it != pred[G].end() && (*it).first >= Ind; ++ it);
	assert(it != pred[G].begin()); it --;
	reconstr(G - (*it).first * (*it).second, (*it).first);
	for (int i = 0; i < (*it).second; ++ i)
		printf("%d\n", (*it).first);
}

void baga_marfa (int start = 1, int end = 200) {
	int last, now, i, deque_st, deque_end, deque_size, rest, k;

	for (i = 0; i <= G; ++ i)
		A[0][i] = A[1][i] = oo;
	A[0][0] = A[1][0] = 0;

	for (i = end, last = 0, now = 1; i >= start; -- i, last ^= 1, now ^= 1) {
		if (! freq[i]) {
			last ^= 1; now ^= 1;
			continue;
		}
		deque_size = i * freq[i];
		for (k = 0; k <= G; ++ k)
			A[now][k] = A[last][k];

		for (rest = 0; rest < i; ++ rest) {
			deque_st = deque_end = 0;
			deque[deque_end ++] = rest;

			for (k = rest + i; k <= G; k += i) {
				if (A[now][k] > A[last][deque[deque_st]] + (k - deque[deque_st]) / i) {
					A[now][k] = A[last][deque[deque_st]] + (k - deque[deque_st]) / i;
					pred[k].push_back(make_pair(i, (k - deque[deque_st]) / i));
				}
				for (; deque_st < deque_end && A[last][deque[deque_end - 1]] + (k - deque[deque_end - 1]) / i > A[last][k]; deque_end --);
				for (; deque_st < deque_end && deque[deque_st] <= k - deque_size; deque_st ++);
				deque[deque_end ++] = k;
			}
		}
	}
	for (; G && A[last][G] == oo; G --);
	if (G == 0) {
		printf("0 0\n");
		exit(0);
	}
	printf("%d %d\n", G, A[last][G]);
	reconstr(G, 1);
}

int main () {
	int i, g;

	freopen("ghiozdan.in", "r", stdin);
	freopen("ghiozdan.out", "w", stdout);

	scanf("%d%d", &N, &G);

	for (i = 1; i <= N; ++ i) {
		scanf("%d", &g);
		freq[g] ++;
	}

	baga_marfa();
}