Pagini recente » Cod sursa (job #1064312) | Cod sursa (job #2474690) | Cod sursa (job #872681) | Cod sursa (job #238191) | Cod sursa (job #519205)
Cod sursa(job #519205)
#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];
int nr[210], Q[MAX_G];
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 st, st + 1 .. dr
int l = 0;
for (int i = st; i <= dr; i++)
if (nr[i] > 0) {
l = 1 - l;
for (int j = 1; j <= m; j++)
c[l][j] = c[1 - l][j];
for (int j = 1; j <= i; j++) { //lucrez pentru greutatea i, si iau in considerare subsirul j, j + i, j + 2*i...
int st = 1, dr = 0;
//initializez deque-ul
for (int k = j + i * ((m - j) / i), count = 1; k >= 0 && count <= nr[i] + 1; k -= i, count++) {
Q[++dr] = k;
while (dr > st && c[l][Q[dr]] + (k - Q[dr]) / i < c[l][Q[dr - 1]] + (k - Q[dr - 1]) / i) {
Q[dr - 1] = Q[dr];
dr--;
}
}
for (int k = j + i * ((m - j) / i); k >= i; k -= i) {
while (Q[st] >= k)
st++;
c[l][k] = min(c[l][k], c[l][Q[st]] + (k - Q[st]) / i);
if (k - (nr[i] + 1) * i >= 0) {
Q[++dr] = k - (nr[i] + 1) * i;
while (dr > st && c[l][Q[dr]] + (k - Q[dr]) / i < c[l][Q[dr - 1]] + (k - Q[dr - 1]) / i) {
Q[dr - 1] = Q[dr];
dr--;
}
}
}
}
for (int j = 1; j <= m; j++)
c[1 - l][j] = inf;
}
for (int i = 1; i <= m; i++)
minNr[lin][i] = c[l][i];
}
void solve(int st, int dr, int val) {
if (val == 0)
return;
if (st == dr) {
while (val) {
val -= st;
printf("%d\n", 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;
}
if (minNr[0][val] < sol) {
sol = minNr[0][val];
pos = val;
}
if (minNr[1][val] < sol) {
sol = minNr[1][val];
pos = 0;
}
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]);
nr[G[i]]++;
}
sort(G + 1, G + n + 1);
work(1, G[n], 0);
for (int i = m; i > 0; i--)
if (minNr[0][i] != inf) {
printf("%d %d\n", i, minNr[0][i]);
solve(1, G[n], i);
break;
}
return 0;
}