Cod sursa(job #3309468)

Utilizator Lex._.Lex Guiman Lex._. Data 4 septembrie 2025 21:53:38
Problema Ghiozdan Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.79 kb
#include <bits/stdc++.h>
#define GMAX 75001
#define NMAX 201
#define inf 1000000000
using namespace std;

ifstream in("ghiozdan.in");
ofstream out("ghiozdan.out");

int frecventa[NMAX]; ///frecventa fiecarei greutati
int dp[GMAX]; ///numarul minim de obiecte pentru fiecare greutate
int ult_poz[GMAX];

int main()
{
    int n, g;
    in >> n >> g;
    for(int i=1; i<=g; i++)
        dp[i]=inf;

    for(int i=1; i<=n; i++)
    {
        int w;
        in >> w;
        frecventa[w]++;
    }
    for(int w=NMAX-1; w>=1; w--)
    {
        int p=1, frecv=frecventa[w];
        while(frecv>=p) ///trucul log2
        {
            for(int i=g; i>=p*w; i--)
            {
                if(dp[i-p*w]+p < dp[i])
                {
                    dp[i]=dp[i-p*w]+p;
                    ult_poz[i]=i-w;
                }
            }
            frecv-=p;
            p*=2;
        }
        if(frecv>0)
        {
            p=frecv;
            for(int i=g; i>=p*w; i--)
            {
                if(dp[i-p*w]+p < dp[i])
                {
                    dp[i]=dp[i-p*w]+p;
                    ult_poz[i]=i-w;
                }
            }
        }
    }
    int g_max;
    for(int i=g; i>=0; i--)
    {
        if(dp[i]!=inf)
        {
            g_max=i;
            break;
        }
    }
    out << g_max << " " << dp[g_max] << "\n";

    //for(int i=1; i<=g; i++) out << dp[i] << " "; out << "\n";
    //for(int i=1; i<=g; i++) out << ult_poz[i] << " "; out << "\n";

    vector<int> greutati; ///afisam greutatile obiectelor puse in ghiozdan
    int poz=g_max;
    while(poz>0)
    {
        greutati.push_back(poz-ult_poz[poz]);
        poz=ult_poz[poz];
    }
    for(auto& w : greutati)
        out << w << "\n";

    return 0;
}