Pagini recente » Cod sursa (job #3273186) | Cod sursa (job #2998732) | Cod sursa (job #3294176) | Cod sursa (job #1568461) | Cod sursa (job #1222534)
#include <fstream>
#define DIM 75010
#define INF 1000000000
using namespace std;
ifstream fin("ghiozdan.in");
ofstream fout("ghiozdan.out");
int F[210];
int D[2][DIM];
//D[i][j] = numarul minim de obiecte pentru a obtine greutatea j
//luand in calcul doar greutatile <= i
int Q[DIM];
int T[2][DIM];
//T[i][j] = ultima valoare j obtinuta cu greutati din prima jumatate a intervalului st, dr
int N, G, i, j, r, x, p, u, step, act;
void rec(int st, int dr, int G) {
int i;
if (G==0)
return;
if (st == dr){
int nr;
for (nr = 1; nr <= F[st] && G - st >= 0; nr++){
fout<<st<<"\n";
G = G - st;
}
return;
}
int mid = (dr + st)/2;
for (i=0;i<=1;i++)
for (j=0;j<=G;j++)
D[i][j] = INF;
D[0][0] = 0;
act = 1;
for (i=st;i<=dr;i++) {
if (F[i] == 0)
continue;
D[0][0] = 0;
D[1][0] = 0;
for (r=i; r>=1; r--) {
//calculez D[i][j] cu j de forma multiplu de i + r
p = 1; u = 0;
for (j=r; j<=G; j+=i) {
D[act][j] = D[!act][j];
if (D[act][j] != INF){
if (i <= mid)
T[act][j] = j;
else
T[act][j] = T[!act][j];
//T[act][j] = 0;
}
if (j-i >= 0 && D[!act][j-i] != INF) {
while (p<=u && D[!act][j-i] < D[!act][ Q[u] ] + (j-i-Q[u])/i) {
u--;
}
Q[++u] = j-i;
}
if ((j-Q[p])/i > F[i])
p++;
if (p <= u) {
if (D[act][j] > D[!act][ Q[p] ] + ( j-Q[p] )/i) {
D[act][j] = D[!act][ Q[p] ] + ( j-Q[p] )/i;
if (i <= mid)
T[act][j] = j;
else
T[act][j] = T[!act][Q[p]];
}
}
}
}
act = !act;
}
int aux;
for (i=G;i>=1;i--)
if (D[!act][i] != INF) {
aux = T[!act][i];
break;
}
if (st == 1 && dr == 200) {
fout<<i<<" "<<D[!act][i]<<"\n";
}
rec(st, mid, aux);
rec(mid+1, dr, i-aux);
}
int main() {
fin>>N>>G;
for (i=1;i<=N;i++) {
fin>>x;
F[x]++;
}
rec(1, 200, G);
/*
for (i=G; i>=1; i--)
if (D[!act][i] != INF) {
fout<<i<<" "<<D[!act][i];
break;
}
*/
return 0;
}