Pagini recente » Profil StarGold2 | Cod sursa (job #1818690) | Cod sursa (job #2950064) | Rating Cabaua Florin-Gabriel (CabauaFlorin) | Cod sursa (job #2225993)
#include <iostream>
#include <fstream>
#include <algorithm>
#include <string.h>
#include <assert.h>
#include <vector>
using namespace std;
#define GMAX 75001
#define NMAX 201
#define INF (1 << 30)
int ap[NMAX];
int sol[GMAX], sol_aux[GMAX], diff[GMAX], deq[GMAX], /* until mij */ um[GMAX], um_aux[GMAX];
vector <int> obj;
void compute(int st, int dr, int g) {
int i, j, cnt;
if (g == 0 || st > dr)
return;
if (st == dr) {
assert(g % st == 0);
for (int i = st; i <= g; i += st)
obj.push_back(st);
return;
}
int mij = (st + dr) / 2;
for (i = 1; i <= g; i++) {
sol[i] = -1;
um[i] = -1;
}
sol[0] = 0;
um[0] = 0;
/*
* Which is the sum of the objects in an optimal solution whose
* weights are <= mij;
*/
for (j = st; j <= dr; j++) {
if (ap[j] > 0) {
cnt = ap[j];
memset(sol_aux, 0, sizeof(sol_aux));
memset(um_aux, 0, sizeof(um_aux));
for (int off = 0; off <= j - 1; off++) {
{
int k = 0;
for (i = off; i <= g; i += j) {
diff[i] = sol[i] - k;
if (sol[i] == -1)
diff[i] = INF;
k++;
}
}
{
int k = 0, st = 1, dr = 0;
for (i = off; i <= g; i += j) {
while (st <= dr && diff[i] <= diff[deq[dr]])
dr--;
deq[++dr] = i;
int idx = (int)max(0LL, 0LL + i - 1LL * cnt * j);
while (deq[st] < idx)
st++;
if (diff[deq[st]] == INF) {
sol_aux[i] = -1;
um_aux[i] = -1;
}
else {
sol_aux[i] = diff[deq[st]] + k;
um_aux[i] = um[deq[st]];
}
k++;
}
}
}
for (i = 0; i <= g; i++)
sol[i] = sol_aux[i];
if (j <= mij) {
for (i = 0; i <= g; i++) {
if (sol[i] == -1)
um[i] = -1;
else
um[i] = i;
}
}
else {
for (i = 0; i <= g; i++) {
um[i] = um_aux[i];
}
}
}
}
for (i = g; i >= 0; i--) {
if (sol[i] != -1)
break;
}
int x = um[i];
compute(st, mij, x);
compute(mij + 1, dr, g - x);
}
int main () {
ios::sync_with_stdio(false);
int n, g, i, cnt, j;
ifstream f("ghiozdan.in");
ofstream G("ghiozdan.out");
f >> n >> g;
for (i = 1; i <= n; i++) {
int x;
f >> x;
ap[x]++;
}
f.close();
for (i = 1; i <= g; i++) {
sol[i] = -1;
}
sol[0] = 0;
for (j = 1; j <= NMAX - 1; j++) {
if (ap[j] == 0)
continue;
cnt = ap[j];
memset(sol_aux, 0, sizeof(sol_aux));
for (int off = 0; off <= j - 1; off++) {
{
int k = 0;
for (i = off; i <= g; i += j) {
diff[i] = sol[i] - k;
if (sol[i] == -1)
diff[i] = INF;
k++;
}
}
{
int k = 0, st = 1, dr = 0;
for (i = off; i <= g; i += j) {
while (st <= dr && diff[i] <= diff[deq[dr]])
dr--;
deq[++dr] = i;
int idx = (int)max(0LL, 0LL + i - 1LL * cnt * j);
while (deq[st] < idx)
st++;
if (diff[deq[st]] == INF)
sol_aux[i] = -1;
else
sol_aux[i] = diff[deq[st]] + k;
k++;
}
}
}
for (i = 0; i <= g; i++)
sol[i] = sol_aux[i];
}
for (i = g; i >= 0; i--) {
if (sol[i] != -1)
break;
}
assert(i >= 0);
G << i << " " << sol[i] << '\n';
compute(1, NMAX - 1, i);
for (vector <int> :: iterator it = obj.begin(); it != obj.end(); it++) {
G << *it << '\n';
}
G.close();
return 0;
}