Pagini recente » Cod sursa (job #1868031) | Cod sursa (job #2320963) | Cod sursa (job #2151580) | Cod sursa (job #346923) | Cod sursa (job #779329)
Cod sursa(job #779329)
#include <stdio.h>
#include <assert.h>
#include <string.h>
#define MAX 200
#define MAXG 30505
int N, G;
short c[MAX + 1];
int best[2][MAXG], up[2][MAXG];
int d[MAXG], p[MAXG], dl, dr;
inline void initdeque() { dl = 0; dr = -1; }
inline void adddeque(int val, int poz, int L)
{
while ( dr >= dl && d[dr] + poz - p[dr] >= val ) dr--;
d[++dr] = val;
p[dr] = poz;
if (poz - p[dl] > L)
dl++;
}
int solve( int l1, int c1, int l2, int c2 )
{
assert( l1 <= l2 && c1 <= c2 );
if (l1 == l2)
{
int k = (c2 - c1) / l1;
assert( c[l1] >= k );
for (; k; k--)
printf("%d\n", l1);
return (c2 - c1) / l1;
}
int m = (l1 + l2) >> 1, i, step = 1;
memset( best[0], 0x3f, sizeof( best[0] ) );
best[0][c1] = 0; up[0][c1] = c1;
for (i = l1; i <= l2; i++, step ^= 1)
{
int j, r;
//nxt[i] = max( prv[i - x * cur] + x | x <= c[cur] && x <= i / cur )
//nxt -> best[step]; prv -> best[1 ^ step]; cur -> i
//deque for every different remainder
for (r = 0; r < i; r++)
{
initdeque();
for (j = c1 + r; j <= c2; j += i)
{
adddeque( best[1 ^ step][j], j / i, c[i] );
best[step][j] = d[dl] + j / i - p[dl];
int np = ( j - ((j / i - p[dl]) * i) );
up[step][j] = (i <= m) ? j : up[1 ^ step][np];
}
}
}
int last = c2, UP, bst;
for (; best[1 ^ step][last] == 0x3f3f3f3f && last >= c1; last--);
bst = best[1 ^ step][last];
if (l1 == 1 && l2 == MAX)
printf("%d %d\n", last, best[1 ^ step][last]);
UP = up[1 ^ step][last];
assert( solve( l1, c1, m, UP ) + solve( m + 1, UP, l2, last ) == bst );
return bst;
}
int main()
{
freopen("ghiozdan.in", "rt", stdin);
freopen("ghiozdan.out", "wt", stdout);
int i, j;
for (scanf("%d %d", &N, &G), i = 0; i < N; i++)
{
scanf("%d", &j);
c[j]++;
}
solve(1, 0, MAX, G);
return 0;
}