Cod sursa(job #2884229)

Utilizator Mihai_EduardMihai Eduard Mihai_Eduard Data 2 aprilie 2022 17:51:11
Problema Ghiozdan Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.97 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("ghiozdan.in");
ofstream fout("ghiozdan.out");
const int inf=1e9;

///dp[i][j]=numarul minim de obiecte necesare cu greutatea<= i pentru a obtine o greutate j
int N, G, f[205], dp[205][1005];
vector<int> sol;
pair<int,int> last[205][1005];
deque<pair<int,int>> dq[205];

int main()
{
    fin>>N>>G;
    int x;
    for(int i=1;i<=N;i++){
        fin>>x;
        f[x]++;
    }

    int sum=0;
    for(int i=200;i>=1 and G>1000;i--){
        while(G>1000 and f[i]){
            G-=i;
            sum+=i;
            f[i]--;
            sol.push_back(i);
        }
    }

    for(int i=0;i<=200;i++)
        for(int j=1;j<=G;j++)
            dp[i][j]=inf;

    for(int i=1;i<=200;i++){
        for(int j=0;j<=G;j++)
            dp[i][j]=dp[i-1][j];
        if(f[i]==0)
            continue;
        for(int j=0;j<i;j++)
            dq[j].clear();
        int nr=f[i];
        for(int j=0;j<=G;j++){
            int rest=j%i;
            while(!dq[rest].empty() and dq[rest].back().first>=dp[i-1][j])
                dq[rest].pop_back();
            dq[rest].push_back({dp[i-1][j],j});
            while(!dq[rest].empty() and (j-dq[rest].front().second)>nr*i)
                dq[rest].pop_front();

            if(dq[rest].front().first+(j-dq[rest].front().second)/i<dp[i][j]){
                dp[i][j]=dq[rest].front().first+(j-dq[rest].front().second)/i;
                last[i][j]={i,(j-dq[rest].front().second)/i};
            }
        }
    }

    while(G>=0){
        if(dp[200][G]!=inf)
            break;
        G--;
    }

    int ind=200, ini=G;
    while(G>0){
        pair<int,int> t=last[ind][G];
        ind--;
        while(t.second--){
            sol.push_back(t.first);
            G-=t.first;
        }
    }
    G=ini;

    fout<<G+sum<<' '<<sol.size()<<'\n';
    for(auto x : sol)
        fout<<x<<'\n';

    fin.close();
    fout.close();
    return 0;
}