Pagini recente » Cod sursa (job #1675077) | Cod sursa (job #2531206) | Cod sursa (job #911475) | Cod sursa (job #2745128) | Cod sursa (job #519180)
Cod sursa(job #519180)
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define MAX_N 20010
#define MAX_G 75010
#define inf 1000000000
int n, m;
int minNr[2][MAX_G], c[2][MAX_G];
int G[MAX_N];
void work(int st, int dr, int lin) {
memset(c, 0, sizeof(c));
for (int i = 1; i <= m; i++)
c[0][i] = inf;
//folosesc greutatile G[st], G[st + 1] .. G[dr]
int l = 0;
for (int i = st; i <= dr; i++) {
l = 1 - l;
for (int j = 1; j <= m; j++)
c[l][j] = c[1 - l][j];
for (int j = 1; j <= G[i]; j++)
for (int k = j + G[i] * ((m - j) / G[i]); k >= j; k -= G[i])
if (k - G[i] >= 0)
c[l][k] = min(c[l][k], c[l][k - G[i]] + 1);
for (int j = 1; j <= m; j++)
c[1 - l][j] = 0;
}
for (int i = 1; i <= m; i++)
minNr[lin][i] = c[l][i];
}
void solve(int st, int dr, int val) {
if (st == dr) {
while (val) {
val -= G[st];
printf("%d\n", G[st]);
}
return;
}
memset(minNr, 0, sizeof(minNr));
work(st, (st + dr) / 2, 0);
work((st + dr) / 2 + 1, dr, 1);
int sol = inf, pos = 0;
for (int i = 1; i <= val; i++)
if (minNr[0][i] + minNr[1][val - i] < sol) {
sol = minNr[0][i] + minNr[1][val - i];
pos = i;
}
solve(st, (st + dr) / 2, pos);
solve((st + dr) / 2 + 1, dr, val - pos);
}
int main() {
freopen("ghiozdan.in", "r", stdin);
freopen("ghiozdan.out", "w", stdout);
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d", &G[i]);
work(1, n, 0);
for (int i = m; i > 0; i--)
if (minNr[0][i] != inf) {
printf("%d %d\n", i, minNr[0][i]);
solve(1, n, i);
break;
}
return 0;
}