Cod sursa(job #19396)

Utilizator MariusMarius Stroe Marius Data 19 februarie 2007 14:05:55
Problema Ghiozdan Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.43 kb
#include <cstdio>
using namespace std;

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

#define MAX_G 75005
#define MAX_V 205
#define INF   1e5

int N, G, F[MAX_V];

int VMax;

int R[2][MAX_G], deque[MAX_G];


void read_in(void)
{
	freopen(iname, "r", stdin);
	int i;
	int V;
	for (scanf("%d %d", & N, & G), i = 0; i < N; ++ i) {
		scanf("%d", & V);
		if (VMax < V)
			VMax = V;
		F[V] ++;
	}
}

void solve(void)
{
	int stp = 0;
	for (int i = 1; i <= G; ++ i)
		R[stp][i] = INF;
	for (int i = 1; i <= VMax; ++ i) {
		stp ^= 1;
		for (int r = 0; r < i; ++ r) {
			int head = 0;
			int tail = 0;
			for (int k = 0; k <= (G - r) / i; ++ k) {
				int j = k * i + r;
				/* scoate din deque */
				while (head < tail && (deque[head] - r) / i < k - F[i])
					head ++;
				/* actualizeaza starea (i, j) */
				if (head < tail)
					R[stp][j] = R[stp ^ 1][deque[head]] + (k - (deque[head] - r) / i);
				else
					R[stp][j] = INF;
				if (R[stp][j] > R[stp ^ 1][j])
					R[stp][j] = R[stp ^ 1][j];
				/* baga in deque */
				while (head < tail && R[stp ^ 1][j] - 1 <= R[stp ^ 1][deque[tail - 1]])
					tail --;
				deque[tail ++] = j;
			}
		}
	}
}

void print_out(void)
{
	freopen(oname, "w", stdout);
	for (; G > 0; -- G) {
		if (R[VMax & 1][G] != INF)	break ;
	}
	printf("%d %d\n", G, R[VMax & 1][G]);
}

int main(void)
{
	read_in();
	solve();
	print_out();
	return 0;
}