Cod sursa(job #951052)

Utilizator Impaler_009Mihai Nitu Impaler_009 Data 19 mai 2013 00:42:38
Problema Ghiozdan Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 1.6 kb
#include <fstream>
using namespace std;
ifstream fin("ghiozdan.in");
ofstream fout("ghiozdan.out");
#define inf 20001
int i,n,g,nr[201],s[75001],ob[75001],x,j,maxw,G;
/*nr[i]=numarul de obiecte de greutate i
(deoarece intervalul de greutati este mult mai mic decat numarul maxim de obiecte
 iar un obiect este identificat numai prin greutatea sa, aceasta reprezentare este mult mai avantajoasa
 s[i]=numarul minim de obiecte ce pot forma greutatea i
 ob[i]= ultimul obiect ce a intrat in compopnenta greutatii i*/

int main ()
{
    fin>>n>>G;
    maxw=0;
    for (i=1;i<=n;i++)
    {
        fin>>x;
        nr[x]++;
        if (x>maxw) maxw=x;
    }
    //for (i=1; i<=G; i++) s[i]=-1;
    s[0]=1;
    for (int w=maxw; w>=1; w--)
    {
        if (nr[w]==0) continue;
        for (i=G; i>=w; i--)
        {
            if (s[i]) continue;
            for (j=1; j<=nr[w] && i>=j*w; j++)
            {
                if (s[i-j*w])               //deoarece luam obiectele in ordinea inversa a greutatii (cele mai grele primele) nu trebuie sa verificam optimalitatea. Prima completare a casutei s[i] va si numarul minim deoarece am folosit cele mai grele obiecte pana in momentul respectiv. Nu are cum sa se acumuleze un numar mai mic de obiecte mai usoare pentru a forma aceasi greutatte.
                {
                    s[i]=s[i-j*w]+j;
                    ob[i]=w;
                    break;
                }
            }
        }
    }
    for (i=G;;i--) if (s[i]) {fout<<i<<" "<<s[i]-1<<"\n"; break;}
    while (i)
    {
        fout<<ob[i]<<"\n";
        i=i-ob[i];
    }
}