Cod sursa(job #929038)

Utilizator horatiu13Horatiu horatiu13 Data 26 martie 2013 20:10:22
Problema Ghiozdan Scor 62
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.77 kb
/*
Zaharel, Nargy si Fumeanu vor sa plece la munte in vacanta. Pentru asta ei au 
cumparat un ghiozdan cat mai incapator, care are o capacitate de G grame. Ei 
au facut si o lista cu N obiecte pe care vor sa le ia cu ei. Nu toate obiectele 
incap in ghiozdan, si fiindca s-au decis sa nu se complice, vor sa umple cat de 
mult se poate ghiozdanul (desigur nu cu mai mult de G grame in total), dar cu un 
numar minim de obiecte.

Prima linie a fisierul de intrare ghiozdan.in va contine numerele naturale N si G 
separate prin spatii. Urmatoarele N linii vor contine cate un numar natural pe linie, 
reprezentand greutatile celor N obiecte.

Pe prima linie din fisierul de iesire ghiozdan.out se vor afisa doua numere naturale 
Gmax si Nmin cu semnificatia ca se poate umple ghiozdanul cu obiecte de greutate totala 
Gmax (Gmax ≤ G), iar numarul minim de obiecte pentru a obtine aceasta greutate este Nmin. 
Urmatoarele Nmin linii vor contine numere naturale reprezentand greutatile obiectelor din 
ghiozdan. Suma acestor numere trebuie sa fie Gmax.

ghiozdan.in			ghiozdan.out
5 9					8 3
2					2
2					2
2					4
2
4

6 24				23 4
19					2
7					7
7					7
7					7
7
2

9 15				15 5
3					3
2					4
3					2
4					3
3					3
3
3
4
3
*/


#include<stdio.h>
#define MAX_N 20001
#define MAX_G 75001

int sol[MAX_G];
int obt[MAX_G];
int ap[200];
int n;
int G;
int maxg;
int MAX=-1;

void citire()
{
	FILE *g=fopen("ghiozdan.in", "r");
	int x;
	fscanf(g, "%d%d", &n, &G);
	for(int i=1; i<=n; i++)
	{
		fscanf(g, "%d", &x);
		ap[x]++;
		if(maxg<x)
			maxg=x;
	}
}

void dinamica()
{
	obt[0]=1;
	for(int i=1; i<=maxg; i++)
		if(ap[i])
		{
			for(int j=G-i; j>=0; j--)
				if(obt[j])
				{
					for(int k=1; k<=ap[i] && j+i*k<=G; k++)
						if(!sol[j+i*k] || sol[j+i*k] > sol[j]+k)
						{
							sol[j+i*k]=sol[j]+k;
							obt[j+i*k]=i;
							if(MAX < j+i*k)
								MAX=j+i*k;
						}
				}
		}
	/*
	sol[v[1]]=1;
	obt[v[1]]=1;
	MAX=v[1];
	for(int i=2; i<=n; i++)
	{
		for(int j=MAX; j>=0; j--)
		{
			if(obt[j] && j+v[i]<=G)
			{
				if(!sol[j+v[i]] || sol[j+v[i]] > sol[j] + 1 )
				{
					sol[j+v[i]]=sol[j]+1;
					obt[j+v[i]] = i;
					if(MAX<j+v[i])
						MAX=j+v[i];
				}
			}
		}
	}
	//*/
}

void afisare()
{
	FILE *g=fopen("ghiozdan.out", "w");
	fprintf(g, "%d %d\n", MAX, sol[MAX]);
	int X=MAX;
	
	while(X)
	{
		fprintf(g, "%d\n", obt[X]);
		X -= obt[X];
	}
}

int main()
{
	citire();
	dinamica();
	afisare();
	/*
	printf("     ");
	for(int i=1; i<=G; i++)
		printf("%3d", i);
	printf("\nsol: ");
	for(int i=1; i<=G; i++)
		printf("%3d", sol[i]);
	printf("\nobt: ");
	for(int i=1; i<=G; i++)
		printf("%3d", obt[i]);
	printf("\n\nMAX: %d\nsol[MAX]: %d", MAX, sol[MAX]);
	//*/
	return 0;
}