Pagini recente » Sedinta 2008-10-10 | Cod sursa (job #1574357) | Rating Cismaru Claudiu (CismaruC) | Profil PlayLikeNeverB4 | Cod sursa (job #163852)
Cod sursa(job #163852)
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define Nmax 20
#define INF 2000000015
#define ll long long
#define MAX(a,b) ((a) >= (b) ? (a) : (b))
#define MIN(a,b) ((a) <= (b) ? (a) : (b))
int n, ct, mask, mask0;
ll t;
int c[Nmax], v[Nmax];
int a[1 << 16];
int b[1 << 16];
char ok[1 << 16];
char DP[1 << 16];
int last[1 << 16];
int pos[1 << 16];
void citire()
{
int i;
scanf("%d %lld\n", &n, &t);
for (i = 1; i <= n; ++i)
scanf("%d %d\n", &c[i], &v[i]);
}
void gcd(ll a, ll b, ll &x, ll &y, ll &d)
{
if (b == 0)
{
d = a;
x = 1;
y = 0;
}
else
{
ll x0, y0;
gcd(b, a % b, x0, y0, d);
x = y0;
y = x0 - a / b * y0;
}
}
void scrie(int p)
{
if (p == 0) return;
printf("%d ", pos[p]);
scrie(last[p]);
}
void back(int p)
{
if (p == n)
{
if (ok[mask0] && DP[mask] > DP[mask ^ mask0] + 1)
{
DP[mask] = DP[mask ^ mask0] + 1;
pos[mask] = b[mask0];
last[mask] = mask ^ mask0;
}
return;
}
back(p + 1);
mask += 1 << p;
back(p + 1);
mask0 += 1 << p;
back(p + 1);
mask -= 1 << p;
mask0 -= 1 << p;
}
void solve()
{
int i, mask;
ll A, B, C, X, Y, D, DX, DY, step;
for (i = 1; i <= n; ++i)
if (c[i] <= t)
{
ok[1 << (i - 1)] = 1;
a[1 << (i - 1)] = v[i];
b[1 << (i - 1)] = c[i];
}
for (mask = 1; mask < 1 << n; ++mask)
if (!ok[mask])
{
for (i = 1; i <= n; ++i)
if (mask & (1 << (i - 1)))
break;
if (!ok[mask ^ (1 << (i - 1))]) break;
A = a[mask ^ (1 << (i - 1))];
B = - v[i];
C = c[i] - b[mask ^ (1 << (i - 1))];
if (A == 0 || B == 0)
{
if (A == 0 && B == 0)
{
if (C == 0)
{
ok[mask] = 1;
a[mask] = 0;
b[mask] = c[i];
}
continue;
}
else
{
if (A == 0 && C % B == 0 && C / B >= 0)
{
ok[mask] = 1;
a[mask] = INF;
b[mask] = b[mask ^ (1 << (i - 1))];
}
if (B == 0 && C % A == 0 && C / A >= 0)
{
ok[mask] = 1;
a[mask] = INF;
b[mask] = c[i];
}
}
continue;
}
gcd(A, B, X, Y, D);
if (C % D != 0) continue;
X *= C / D;
Y *= C / D;
DX = abs(B / D);
DY = abs(A / D);
if (X < 0 || Y < 0)
{
step = MAX(-X / DX, -Y / DY);
X += step * DX;
Y += step * DY;
if (X < 0 || Y < 0)
X += DX, Y += DY;
}
if (X >= DX && Y >= DY)
{
step = MIN(X / DX, Y / DY);
X -= step * DX;
Y -= step * DY;
}
if (c[i] + v[i] * Y <= t)
{
ok[mask] = 1;
a[mask] = MIN(INF, abs(A * B / D));
b[mask] = c[i] + v[i] * Y;
}
}
memset(DP, 0x3f, sizeof(DP));
DP[0] = 0;
back(0);
printf("%d\n", DP[(1 << n) - 1]);
scrie((1 << n) - 1);
}
int main()
{
freopen("vanatoare.in", "r", stdin);
freopen("vanatoare.out", "w", stdout);
citire();
solve();
return 0;
}