Pagini recente » Cod sursa (job #232257) | Cod sursa (job #278220) | Cod sursa (job #1834313) | Cod sursa (job #2682776) | Cod sursa (job #3335471)
#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 << "facem pt nr = " << nr << '\n';
for(int x = g; x >= 0; x--){
// cout << " -- > il consider pe 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] + (x - k) / nr);
// cout << " -- > consider sa fur de la k = " << k << " cu dp = " << dp1[k] << '\n';
}
}
}
// 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;
}