Pagini recente » Cod sursa (job #2042807) | Cod sursa (job #1861249) | Cod sursa (job #1235252) | Cod sursa (job #1166360) | Cod sursa (job #572174)
Cod sursa(job #572174)
//by Puni Andrei-Paul
//Time complexity: O(N*D*log D)
//Space complexity: O(N*D)
//Method: DP + deque
//Working time: 45 minutes
#include <cstdio>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <vector>
using namespace std;
#define Nmax 51
#define Emax 400000
#define Dmax 10001
#define Inf best[0][0]
int N,E, d[Nmax];
int best[Nmax][Dmax];
int dq[Dmax], st, dr;
bool se_poate(int D)
{
memset(best, 0x3f, sizeof best);
//si in rest infinit ... pt ca nu pot sa il misc pe 1 ..
best[1][0] = 0;
for (int i = 2; i <= N; ++i)
{
//init dq
st = 1; dr = 0;
for (int j = 0; j <= d[N]; ++j)
{
//le scoti pe alea de care nu ai nevoie
while (st <= dr && abs(j - dq[st]) > D)
++st;
//le scoti pe alea care nus destul de bune
while (st <= dr && best[i-1][dq[dr]] >= best[i-1][j])
--dr;
//bagi aia noua
dq[++dr] = j;
best[i][j] = abs(d[i]-j) + best[i-1][dq[st]];
if (best[i][j] > Inf)
best[i][j] = Inf;
}
}
return (best[N][d[N]] <= E);
}
int main()
{
assert(freopen("stalpi.in", "r", stdin) != NULL);
assert(freopen("stalpi.out", "w", stdout) != NULL);
assert(scanf("%d%d", &N, &E) == 2);
assert(3 <= N && N < Nmax);
assert(1 <= E && E <= Emax);
for (int i = 2; i <= N; ++i)
{
assert(scanf("%d", &d[i]) == 1);
assert(d[i-1] <= d[i] && d[i] < Dmax);
}
int ret = d[N];
for (int i = 1<<20; i > 0; i /= 2)
if (ret - i >= 0)
if (se_poate(ret - i))
ret -= i;
printf("%d\n", ret);
return 0;
}