Cod sursa(job #779232)

Utilizator mihaipopa12Popa Mihai mihaipopa12 Data 17 august 2012 03:06:07
Problema Ghiozdan Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.09 kb
#include<stdio.h>

#define maxg 200
#define maxG 75005
#define b 40

using namespace std;

FILE*f=fopen("ghiozdan.in","r");
FILE*g=fopen("ghiozdan.out","w");

int n,G;
int fr[maxg+1],A[maxG],B[maxG],T[b][maxG+1];
int front[maxg+1],back[maxg+1],*deq[maxg+1];
const int inf = 1<<29;

inline void dinamica ( int lim ){
	
	for ( int i = 1 ; i <= G ; ++i ){
		A[i] = inf;
	}
	
	for ( int i = 1 ; i <= lim ; ++i ){
		int line = i % b;
		
		for ( int j = 0 ; j < i ; ++j ){
			if ( j < i-1 )	delete deq[j];
			deq[j] = new int[G/i+2];
			front[j] = back[j] = 1;
			deq[j][1] = j;
		}
		
		for ( int j = 0 ; j <= G ; ++j ){
			B[j] = A[j];
			T[line][j] = j;
		}
		
		if ( !fr[i] )	continue ;
		
		for ( int j = i ; j <= G ; ++j ){
			int list = j % i;
			int pos = deq[list][front[list]];
			
			if ( (j-pos)/i > fr[i] ){
				++front[list];
				if ( front[list] <= back[list] )
					pos = deq[list][front[list]];
				else{
					pos = -1;
				}
			}
			
			if ( pos != -1 && A[pos] + (j-pos)/i < B[j] ){
				B[j] = A[pos] + (j-pos)/i;
				T[line][j] = pos;
			}
			
			while ( front[list] <= back[list] ){
				int pos = deq[list][back[list]];
				if ( A[pos]+(j-pos)/i > A[j] ){
					--back[list];
				}
				else{
					break ;
				}
			}
			deq[list][++back[list]] = j;
		}
		
		for ( int j = 0 ; j <= G ; ++j ){
			A[j] = B[j];
		}
	}
}

int main () {
	
	fscanf(f,"%d %d",&n,&G);
	int x;
	for ( int i = 1 ; i <= n ; ++i ){
		fscanf(f,"%d",&x);
		++fr[x];
	}
	
	dinamica(200);
	
	int sol;
	for ( int i = G ; i >= 0 ; --i ){
		if ( A[i] != inf ){
			fprintf(g,"%d %d\n",i,A[i]);
			sol = i;
			break ;
		}
	}
	
	int lim = 199;
	for ( int i = 200 ; i >= 200 ; --i ){
		for ( int j = sol - T[i%b][sol] ; j > 0 ; j -= i ){
			fprintf(g,"%d\n",i);
		}
		sol = T[i%b][sol];
	}
	while ( lim > 0 ){
		
		dinamica(lim);
		for ( int i = lim ; i >= lim-b && i >= 0 ; --i ){
			for ( int j = sol - T[i%b][sol] ; j > 0 ; j -= i ){
				fprintf(g,"%d\n",i);
			}
			sol = T[i%b][sol];
		}
		
		lim -= b;
	}
	
	fclose(f);
	fclose(g);
	
	return 0;
}