Cod sursa(job #19413)

Utilizator gcosminGheorghe Cosmin gcosmin Data 19 februarie 2007 14:43:12
Problema Ghiozdan Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.88 kb
#include <stdio.h>
#include <queue>
using namespace std;

#define BUC 15
#define GMAX 75010

int N, G;
int nr[210];

int lin[16][GMAX];
int jeg[16][GMAX];
int pred[16][GMAX];
int aux[GMAX];

deque <pair<int, int> > deck[200];

int recsol(int cur, int urm)
{
	int i, j, q, mod, w;
	
	for (j = 1, i = cur; j < urm - cur + 1; i++, j++) {
		for (q = 0; q < i; q++) deck[q].clear();

		for (q = 0, mod = 0; q <= G; q++) {
			while (!deck[mod].empty() && deck[mod].front().second < q - nr[i] * i) deck[mod].pop_front();

			if (jeg[j-1][q] || !q) {
				w = jeg[j-1][q];
				while (!deck[mod].empty() && deck[mod].back().first + (q - deck[mod].back().second) / i > w) deck[mod].pop_back();
				deck[mod].push_back(make_pair(w, q));
			}

			if (!deck[mod].empty()) jeg[j][q] = deck[mod].front().first + (q - deck[mod].front().second) / i, pred[j][q] = (q - deck[mod].front().second) / i;
			else jeg[j][q] = 0, pred[j][q] = 0;

			mod++;
			if (mod == i) mod = 0;
		}
	}

return j;
}

int main()
{
	int i, q, j, cur, urm, cbuc;
	
	freopen("ghiozdan.in", "r", stdin);
	freopen("ghiozdan.out", "w", stdout);

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

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

	for (cur = 1, urm = BUC + 1, i = 1, cbuc = 1; i <= 200; cur = urm, urm += BUC, cbuc++) {
		if (urm > 200) urm = 201;

		j = recsol(cur, urm);
		
		memcpy(lin[cbuc], jeg[1], sizeof(jeg[1]));
		memcpy(jeg[0], jeg[j - 1], sizeof(jeg[0]));		

		if (urm == 201) break;
 	}	

	int sol = 0;
	for (i = 1; i <= G; i++) if (jeg[j-1][i]) sol = i;
	printf("%d %d\n", sol, jeg[j-1][sol]);

	for (; cbuc >= 1; urm = cur, cur -= BUC, cbuc--) {
		memcpy(jeg[0], lin[cbuc], sizeof(jeg[0]));
		recsol(cur, urm);

		for (i = urm - 1, j = urm - cur; i >= cur; i--, j--) {
			for (q = 1; q <= pred[j][sol]; q++) printf("%d\n", i);
			sol -= pred[j][sol] * i;
//			if (pred[j][sol]) printf("%d\n", sol);
		}		
	}

fclose(stdin);
fclose(stdout);
return 0;
}