Pagini recente » Cod sursa (job #2032714) | Cod sursa (job #1856142) | Cod sursa (job #2899864) | Cod sursa (job #2018921) | Cod sursa (job #626630)
Cod sursa(job #626630)
/*
d[i][j] -> nr min de obiecte pt a obtine greutatea j
folosind obiectele de la 1 la i
d[i][j] = min(d[i-1][j],d[i-1][j-g[i]] + 1)
unde g[i] este greutatea obiectului nr i
dinamica pe 2 linii
pt reconstituirea drumului folosesc ca la sol in O(N)
de la cmlsc din arhiva educationala (cel mai lung subsir
comun) vectorul cu pozitie de sosire pe linia n/2.
initializarile pt fiecare apel recursiv sunt cele
obisnuite (consider ce obiecte as lua din intervalul x1...x2)
*/
#include <cstdio>
const int INF = 2000000000;
const int G = 75005;
const int N = 20005;
int d[2][G];
int g[N]; int n; int g_max;
int v[G],v_pred[G];/* sosirea liniei curente pe linia n/2
(in cazul nostru cel mai din dreapta
pct, la alte dinamici primul pct de
sosire a drumului in sens invers pe
linia (x1+x2)/2) */
inline int min(int a, int b)
{
return (a<b)?a:b;
}
void citire()
{
scanf("%d%d",&n,&g_max);
for (int i = 1; i <= n; ++i)
scanf("%d",&g[i]);
}
void dinamica(int x1, int y1, int x2, int y2)
{
//cazul banal
if (x1 == x2)//greut maxima ce se obtine luand un obiect
{
if (1 == n)//nu s-a apucat afisarea primelor 2 valori cerute
if (g[x1] <= y2-y1+1)
printf("%d %d\n",g[x1],1);
else
printf("%d %d\n",0,0);
if (g[x1] <= y2-y1+1)
printf("%d\n",g[x1]);
return;
}
//initializare
d[0][y1-1] = 0;
for (int j = y1; j <= y2; ++j)
d[0][j] = INF; //0%2
//calculare
for (int i = x1; i <= x2; ++i)
{
d[i%2][y1-1] = 0;//init
for (int j = y1; j <= y2; ++j) //% nu merge pt numere negative (decat %2)
{
if (j - g[i] < y1-1)
d[i%2][j] = d[(i-1)%2][j];
else
d[i%2][j] = min(d[(i-1)%2][j],d[(i-1)%2][j-g[i]]+1);
if (i == (x1+x2)/2)
v[j] = j;
if (i > (x1+x2)/2)
if (j - g[i] < y1 - 1)
v[j] = v_pred[j];
else
if (d[(i-1)%2][j] < d[(i-1)%2][j-g[i]]+1)
v[j] = v_pred[j];
else
v[j] = v_pred[j-g[i]];
}
for (int j = y1; j <= y2; ++j)
v_pred[j] = v[j];
}
//calculare greutate maxima posibila
int j_umplere;
for (int j = y2; y1-1 <= j; --j)
if (d[x2%2][j] != INF)
{
j_umplere = j;
break;
}
if (x1 == 1 && y1 == 1 && x2 == n && y2 == g_max)
printf("%d %d\n",j_umplere,d[x2%2][j_umplere]);
int aux = v[j_umplere];
dinamica(x1,y1,(x1+x2)/2,aux);
dinamica((x1+x2)/2+1,aux,x2,y2);
}
int main()
{
freopen("ghiozdan.in","r",stdin);
freopen("ghiozdan.out","w",stdout);
citire();
dinamica(1,1,n,g_max);
return 0;
}