Cod sursa(job #2393046)

Utilizator Alex18maiAlex Enache Alex18mai Data 30 martie 2019 18:50:37
Problema Ghiozdan Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.86 kb

//ALEX ENACHE

#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <unordered_map>
#include <time.h>
#include <iomanip>
#include <deque>
#include <math.h>
#include <cmath>
#include <assert.h>
#include <stack>
#include <bitset>
#include <random>
#include <chrono>

using namespace std;

//#include <iostream>
#include <fstream>
ifstream cin ("ghiozdan.in");ofstream cout ("ghiozdan.out");

int fv[210];
int dp[2][75100];
int last[75100];

set <pair < int , int > > s[210];

const int inf = 1e9;

int main() {

    //freopen("input", "r", stdin);freopen("output", "w", stdout);

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cout << setprecision(10) << fixed;
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    srand(time(NULL));

    int n , g;
    cin>>n>>g;

    for (int i=1; i<=n; i++){
        int x;
        cin>>x;
        fv[x]++;
    }

    for (int i=1; i<=g; i++){
        dp[0][i] = inf;
        dp[1][i] = inf;
    }

    for (int i=200; i>=1; i--){
        if (!fv[i]){
            continue;
        }
        for (int j=0; j<i; j++){
            s[j].clear();
        }
        int maxx = n/i;
        s[0].insert({maxx , 0});
        for (int j=1; j<=g; j++){
            int r = j%i;
            int st = j-(fv[i]+1)*i;

            if (s[r].empty()){
                if (dp[0][j] != inf){
                    s[r].insert({dp[0][j] + maxx - j/i , j});
                }
                continue;
            }
            if (st >= 0 && s[r].find({dp[0][st] + maxx - st/i , st}) != s[r].end()){
                //cout<<"sterg "<<st<<'\n';
                s[r].erase(s[r].find({dp[0][st] + maxx - st/i , st}));
            }
            if (s[r].empty()){
                if (dp[0][j] != inf){
                    s[r].insert({dp[0][j] + maxx - j/i , j});
                }
                continue;
            }
            pair < int , int > best = *s[r].begin();
            if (dp[0][j] > dp[0][best.second] + (j - best.second) / i){
                //cout<<i<<" "<<j<<" "<<best.second<<" "<<dp[0][best.second]<<" "<<dp[0][j]<<' ';
                dp[1][j] = dp[0][best.second] + (j - best.second) / i;
                //cout<<dp[1][j]<<'\n';
                last[j] = best.second;
            }
            if (dp[0][j] != inf){
                s[r].insert({dp[0][j] + maxx - j/i , j});
            }
        }
        for (int j=1; j<=g; j++){
            dp[0][j] = dp[1][j];
        }
    }

    int ans = 0;

    for (int i=0; i<=g; i++){
        if (dp[0][i] != inf){
            ans = i;
        }
    }

    cout<<ans<<" "<<dp[0][ans]<<'\n';

    int now = ans;

    while (now){
        int dif = now - last[now];
        int afis = dif / (dp[0][now] - dp[0][last[now]]);
        for (int i=1; i<=dif/afis; i++){
            cout<<afis<<'\n';
        }
        now = last[now];
    }

    return 0;
}