Cod sursa(job #779140)

Utilizator mihaipopa12Popa Mihai mihaipopa12 Data 16 august 2012 19:36:17
Problema Ghiozdan Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2 kb
#include<stdio.h>
#include<deque>

#define maxg 200
#define maxG 75005
#define b 20

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];
const int inf = 1<<29;
deque<int>deq[maxg+1];

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 ){
			deq[j].clear();
			deq[j].push_back(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].begin();
			
			if ( (j-pos)/i > fr[i] ){
				deq[list].pop_front();
				if ( !deq[list].empty() )
					pos = *deq[list].begin();
				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 ( !deq[list].empty() ){
				int pos = *deq[list].begin();
				if ( A[pos]+(j-pos)/i > A[j] ){
					deq[list].pop_back();
				}
				else{
					break ;
				}
			}
			deq[list].push_back(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 != -1 ){
		
		dinamica(lim);
		for ( int i = lim ; i >= lim-b ; --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;
}