Cod sursa(job #19208)

Utilizator crusRus Cristian crus Data 18 februarie 2007 21:56:10
Problema Ghiozdan Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.73 kb
#include <stdio.h>
#include <string.h>
#define input "ghiozdan.in"
#define output "ghiozdan.out"
#define nmax 20001
#define gmax 75001
long n,g,i,s1[gmax],s2[gmax],max,j,in,min1,min2,m;
int v[nmax],t[gmax],l1,l2,k1;
void read()
{
	FILE *fin;
	fin=fopen(input,"r");
	fscanf(fin,"%ld %ld",&n,&g);
	for (i=1;i<=n;i++)
		fscanf(fin,"%ld",&v[i]);
	fclose(fin);
}
inline long maxim(long a,long b)
{
	if (a>=b) return a;
	return b;
}
inline long minim(long a,long b)
{
	if (a<b) return a;
	return b;
}
void sort(int ls,int ld)
{
	if (ls<ld)
		{
		 int k;
		 k=(int)((ls+ld)/2);
		 sort(ls,k);
		 sort(k+1,ld);
		 l1=0;
		 l2=0;
		 for (i=ls;i<=k;i++)
			 s1[++l1]=v[i];
		 for (i=k+1;i<=ld;i++)
			 s2[++l2]=v[i];
		 i=1;j=1;
		 k=ls-1;
		 while (i<=l1&&j<=l2)			
			 if (s1[i]>s2[j]) v[++k]=s1[i++];
			    else v[++k]=s2[j++];			       
		 for (k1=i;k1<=l1;k1++)		
			 v[++k]=s1[k1];
		 for (k1=j;k1<=l2;k1++)		
			 v[++k]=s2[k1];
		}
}
void solve()
{
	n=n;
	sort(1,n);
	memset(s1,0,sizeof(s1));
	memset(s2,0,sizeof(s2));
	s1[0]=1;
	max=0;
	for (i=1;i<=n;i++)
		{
		max=minim(max+v[i],g);
		for (j=max;j>=0;j--)			
			if (j<v[i]) s2[j]=s1[j];
			else
			{
				min1=s1[j];
				min2=s1[j-v[i]];
				if (min1>0&&(min1<min2||min2==0))
					{
					 s2[j]=min1;					 
					}
				else
				if (min2>0&&(min2<min1||min1==0))
					{
					 s2[j]=min2+1;
					 t[j]=v[i];
					}
             if (s2[j]&&j>=m) m=j;
			}
         memcpy(s1,s2,sizeof(s1));
		}			
}
void write()
{
	FILE *fout;
	fout=fopen(output,"w");	
	fprintf(fout,"%ld %ld\n",m,s2[m]-1);
	while (m>0)
		{
		 fprintf(fout,"%ld\n",t[m]);
		 m-=t[m];
		}
	fclose(fout);
}
int main()
{
	read();
	solve();
	write();
	return 0;
}