Cod sursa(job #1178057)

Utilizator PenReturnedIsUNIBUC ion824 mathboy andreiv PenReturnedIs Data 26 aprilie 2014 14:18:32
Problema Problema rucsacului Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 2.29 kb
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

struct obiect
{
	double val;
	int p,g;
}	thing[5006];

int cmp(const obiect &x, const obiect &y)
{
	return x.val * (double)y.g > (double)x.g * y.val;
}

struct rucsac
{
	obiect Divizible;
	bool oneDiv, ok;
	double val;
} subRucsac[10009];

int main()
{
	int T;
	
	freopen("rucsac.in", "r", stdin);
	freopen("rucsac.out", "w", stdout);T = 1;
	//scanf("%d", &T);
	while (T--)
	{
		int N;int capacity;
		scanf("%d %d", &N, &capacity);
		for (int i = 1; i <= N; ++i)
			scanf("%d %lf", &thing[i].g, &thing[i].val);
			//scanf("%lf %d %d", &thing[i].val, &thing[i].g, &thing[i].p);
		sort(thing + 1, thing + N + 1, cmp);	
		memset(subRucsac, 0, sizeof(subRucsac));
		subRucsac[0].ok = true;
		for (int i = 1; i <= N; ++i)
		{			
			for (int g = capacity; g >= 0; --g)
			if (subRucsac[g].ok)	
			{
				if (g + thing[i].g <= capacity && subRucsac[g].val + thing[i].val > subRucsac[g + thing[i].g].val)
				{
					subRucsac[g + thing[i].g].val = subRucsac[g].val + thing[i].val;
					subRucsac[g + thing[i].g].ok = true;
					if (thing[i].p)
						subRucsac[g + thing[i].g].oneDiv = true, subRucsac[g + thing[i].g].Divizible = thing[i];
				} else
				{
					obiect lastDivizible; bool oneDiv = false;
					if (thing[i].p)
						oneDiv = true, lastDivizible = thing[i];
					else
						if (subRucsac[g].oneDiv)
							oneDiv = true, lastDivizible = subRucsac[g].Divizible;
						
					
					if (oneDiv)
					{
						double availableG = capacity - g + lastDivizible.g - thing[i].g;
						double divizibleG = lastDivizible.g;
						double dividedVal = lastDivizible.val * availableG / divizibleG;					
						if (availableG > 0 && subRucsac[g].val + thing[i].val + dividedVal - lastDivizible.val > subRucsac[capacity].val)
						{
							subRucsac[capacity].val = subRucsac[g].val + thing[i].val + dividedVal - lastDivizible.val;
							subRucsac[capacity].oneDiv = oneDiv;
							subRucsac[capacity].Divizible = lastDivizible;
							subRucsac[capacity].ok = true;
						}
					}
				}					
			}
		}
		double currentVal = 0;
		for (int i = 0; i <= capacity; ++i)
			if (subRucsac[i].val > currentVal)
				currentVal = subRucsac[i].val;
		printf("%.0lf\n", currentVal);	
	}
	
	return 0;
}