Cod sursa(job #928368)

Utilizator horatiu13Horatiu horatiu13 Data 26 martie 2013 13:43:56
Problema Ghiozdan Scor 48
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.44 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 v[MAX_N];
int sol[MAX_G];
int obt[MAX_G];
int n;
int G;
int MAX=-1;

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

void dinamica()
{
	obt[0]=1;
	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", v[obt[X]]);
		//printf("%d %d\n", v[obt[X]], X-v[obt[X]]);
		X -= v[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;
}