Pagini recente » Cod sursa (job #2132671) | Cod sursa (job #2455183) | Cod sursa (job #1140894) | Cod sursa (job #296424) | Cod sursa (job #19216)
Cod sursa(job #19216)
#include <cstdio>
#include <deque>
using namespace std;
#define inf 1000000000
#define rad 14
#define Nmax 20001
#define Gmax 75001
#define Vmax 205
#define x first
#define pos second
#define mp make_pair
#define sz size()
int n, g, a, smax, s, maxv, size;
int ct[Vmax];
int sol[21][Gmax];
int sol2[11][Gmax];
char nr[21][Gmax];
int Q[Gmax];
void citire()
{
int i;
scanf("%d %d\n", &n, &g);
for (i = 1; i <= n; ++i)
{
scanf("%d\n", &a);
++ct[a];
if (a > maxv)
maxv = a;
}
}
void scrie(int num, int suma)
{
if (num == 0)
return;
ct[num] = nr[num][suma];
suma -= num * ct[num];
scrie(num - 1, suma);
}
void solve()
{
int i, j, k, l, st, dr, pas, gr = 1;
memset(sol, 0x3f, sizeof(sol));
memset(sol2, 0x3f, sizeof(sol2));
sol[0][0] = 0;
sol2[0][0] = 0;
for (pas = 0; pas <= 199; pas += 20, ++gr)
{
for (i = 1; i <= 20; ++i)
{
if (ct[pas + i])
{
for (j = 0; j < pas + i; ++j)
{
st = 1;
dr = 0;
if (j == 0)
Q[++dr] = 0;
for (k = j; k <= g; k += pas + i)
{
if (st <= dr)
while (k - Q[st] > ct[pas + i] * (pas + i))
++st;
sol[i][k] = sol[i-1][k];
nr[i][k] = 0;
if (st <= dr)
if (sol[i-1][Q[st]] + ((k - Q[st]) / (pas + i)) < sol[i][k])
{
sol[i][k] = sol[i-1][Q[st]] + ((k - Q[st]) / (pas + i));
nr[i][k] = (k - Q[st]) / (pas + i);
}
while (st <= dr && sol[i - 1][Q[dr]] > sol[i - 1][k])
--dr;
Q[++dr] = k;
}
}
}
for (j = 0; j <= g; ++j)
sol[i][j] = min(sol[i][j], sol[i-1][j]);
/*
for (j = 0; j <= g; ++j)
printf("%d ", sol[i][j]);
printf("\n");
*/
}
//printf("\n");
for (j = 0; j <= g; ++j)
sol2[gr][j] = sol[20][j];
memset(sol, 0x3f, sizeof(sol));
for (j = 0; j <= g; ++j)
sol[0][j] = sol2[gr][j];
}
--gr;
for (smax = g; smax >= 0; --smax)
if (sol2[gr][smax] < inf)
break;
printf("%d %d\n", smax, sol2[gr][smax]);
//printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
for (pas = 180; pas >= 0; pas -= 20, --gr)
{
memset(sol, 0x3f, sizeof(sol));
memset(nr, 0, sizeof(nr));
for (j = 0; j <= g; ++j)
sol[0][j] = sol2[gr - 1][j];
for (i = 1; i <= 20; ++i)
{
if (ct[pas + i])
{
for (j = 0; j < pas + i; ++j)
{
st = 1;
dr = 0;
if (j == 0)
Q[++dr] = 0;
for (k = j; k <= g; k += pas + i)
{
if (st <= dr)
while (k - Q[st] > ct[pas + i] * (pas + i))
++st;
sol[i][k] = sol[i-1][k];
nr[i][k] = 0;
if (st <= dr)
if (sol[i-1][Q[st]] + ((k - Q[st]) / (pas + i)) < sol[i][k])
{
sol[i][k] = sol[i-1][Q[st]] + ((k - Q[st]) / (pas + i));
nr[i][k] = (k - Q[st]) / (pas + i);
}
while (st <= dr && sol[i - 1][Q[dr]] > sol[i - 1][k])
--dr;
Q[++dr] = k;
}
}
}
for (j = 0; j <= g; ++j)
sol[i][j] = min(sol[i][j], sol[i-1][j]);
/*
for (j = 0; j <= g; ++j)
printf("%d ", sol[i][j]);
printf("\n");
*/
}
//printf("\n");
for (i = 20; i > 0; --i)
if (nr[i][smax])
{
for (j = 1; j <= nr[i][smax]; ++j)
printf("%d\n", i + pas);
smax -= nr[i][smax] * (pas + i);
}
}
}
int main()
{
freopen("ghiozdan.in", "r", stdin);
freopen("ghiozdan.out", "w", stdout);
citire();
solve();
return 0;
}