Cod sursa(job #3335500)

Utilizator iulia_morariuIuli Morariu iulia_morariu Data 22 ianuarie 2026 19:38:04
Problema Ghiozdan Scor 54
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.86 kb
#include <algorithm>
#include <iostream>
#include <fstream>
#include <climits>
#include <vector>
#include <queue>
#include <cmath>
// #include <bits/stdc++.h>
#define in  fin
#define out fout

using namespace std;
using ll = long long;
const int GMAX = 75005, NMAX = 20000;

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

int n, g;
int dp[2][GMAX];
int last[2][GMAX]; // l-as fi numit r da coincide cu ala din divide
int v[NMAX];
int vf[201]; // minimude201 reference
ll dp1[GMAX];

// void imparte_si_cucereste(int l, int r, int x){ // care e modul bun sa fac pe L - R costul x?
//     if(l == r){ // cred ca am lowkey terminat
//         int cnt = x / l; // ca gen de atatea ori il pun
//         if(cnt > vf[x]) out << "oh no\n"; // nush ce sa fac daca se intampla asta deci osa sper ca nu se intampla
//         for(int i = 0; i < cnt; i++) out << l << '\n';
//         return;
//     }

//     // acuma eu idk exact ce vrea sa fie ala cu deque ca uhm
//     // mi cam lene sa fac calumea asa ca facem asa

//     for(int i = 1; i <= x; i++) dp[0][i] = INT_MAX;
//     dp[0][0] = 0;

//     for(int i = l; i <= r; i++){ // cu nr de la l la r
//         if(vf[i] == 0) continue; // nobody needs you, i
//         for(int j = 1; j <= x; j++){
//             for(int fr = 0; fr < min( j / i, vf[i] ); fr++){
//                 if(dp[(i - 1) % 2][j - fr * i] == INT_MAX) break; // hell nah
//                 if(dp[(i - 1) % j][j - fr * i] + 1 < dp[i % 2][j]){
//                     dp[i % 2][j] = dp[(i - 1) % j][j - fr * i] + 1;
//                     last[i % 2][j] = last[(i - 1) % j][j - fr * i] + 1;
//                 }
//             }
//         }
//     }
// }

signed main(){
    ios_base::sync_with_stdio(false);
    in.tie(NULL);

    in >> n >> g;
    for(int i = 0; i < n; i++){
        in >> v[i];
        vf[ v[i] ]++;
    }

    // initial trebe sa fac dinamica simpla
    // uhhhhhghhhh chiar n-am chef

    for(int i = 0; i <= g; i++) dp1[i] = INT_MAX;

    dp1[0] = 0;
    for(int nr = 200; nr >= 1; nr--){
        // trebe sa rezolv g-urile cu gen bazat pe resturi
        // cu deque
        // ma rog initial osa fie libidinos si inoptim dar we will deal with that in a moment
        if(vf[nr] == 0) continue;
        // cout << "sunt la nr = " << nr << '\n';
        for(int x = g; x >= 0; x--){
            // cout << "--> incerc sa fac x = " << x << '\n';
            for(int k = x - nr; k >= 0 && (x - k) / nr <= vf[nr]; k -= nr){
                if(dp1[k] == INT_MAX) continue;
                dp1[x] = min(dp1[x], dp1[k] - k / nr + x / nr);
                // cout << "----> pot fura de la k = " << k << " dp = " << dp1[k] << 
            }
        }
    }

    // cout << "dp1 : ";
    // for(int i = 0; i <= g; i++) cout << dp1[i] << " ";
    // cout << '\n';

    int last = g;
    while(dp1[last] == INT_MAX) last--;
    out << last << " " << dp1[last] << '\n';

    return 0;
}