Cod sursa(job #18849)

Utilizator MariusMarius Stroe Marius Data 18 februarie 2007 14:20:27
Problema Ghiozdan Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.81 kb
#include <cstdio>
using namespace std;

const char iname[] = "ghiozdan.in";
const char oname[] = "ghiozdan.out";

#define MAX_G 101
#define MAX_V 101
#define INF   1e5

struct queue_node {
	int x;
	int v;
} Q[MAX_V][MAX_G];

int G, N, F[MAX_V];

int D[2][MAX_G];

int U[MAX_V][MAX_G], P[MAX_V][2];

int CNT;


void read_in(void)
{
	freopen(iname, "r", stdin);
	int i;
	int V;
	int max = 0;

	for (scanf("%d %d", & N, & G), i = 1; i <= N; ++ i) {
		scanf("%d", & V);
		F[V] ++;
		if (max < V)
			max = V;
	}
	CNT = N, N = max;
}

void init_deques(void)
{
	int i;
	for (i = 0; i <= N; ++ i)
		P[i][0] = 1, P[i][1] = 0;
}

void insert(int V, int sum)
{
	int stp = V & 1;
	int l, r;
	int q, y, nv;
	q = sum % V;
	l = P[q][0];
	r = P[q][1];
	y = (MAX_G * V + q - sum) / V;
	nv = D[stp ^ 1][sum] + y;
	while (l <= r && Q[q][r].v > nv)
		r --;
	r ++;
	Q[q][r].v = nv;
	Q[q][r].x = sum;
	P[q][1] = r;
}

int query(int V, int sum)
{
	int l, r, q;
	q = sum % V;
	l = P[q][0];
	r = P[q][1];
	while (l <= r && ((sum - Q[q][l].x) / V) > F[V])
		l ++;
	P[q][0] = l;
	return Q[q][l].x;
}

void solve(void)
{
	int i;
	int j;
	int ret;
	int stp = 0;
	for (i = 1; i <= G; ++ i)
		D[stp][i] = INF;
	for (i = 1; i <= N; ++ i) {
		stp ^= 1;
		init_deques();
		for (j = 0; j <= G; ++ j) {
			insert(i, j);
			ret = query(i, j);
			U[i][j] = (j - ret) / i;
			D[stp][j] = D[stp ^ 1][ret] + U[i][j];
		}
	}
}

void print_out(void)
{
	int i = N;
	int j = G;
	int k;
	for (; j > 0; -- j)
		if (D[N & 1][j] <= CNT)		break ;

	freopen(oname, "w", stdout);

	printf("%d %d\n", j, D[N & 1][j]);
	for (; i > 0; j -= U[i][j] * i, i --)
		for (k = 1; k <= U[i][j]; ++ k)
			printf("%d\n", i);
}

int main(void)
{
	read_in();
	solve();
	print_out();

	return 0;
}