Pagini recente » Cod sursa (job #2468664) | Cod sursa (job #621844) | dopaj | Cod sursa (job #1761874) | Cod sursa (job #166952)
Cod sursa(job #166952)
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define Nmax 32
#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, t, ct, mask, mask0;
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];
int list[Nmax];
void citire()
{
int i;
scanf("%d %d\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, c = a / b;
gcd(b, a - b * c, x0, y0, d);
x = y0;
y = x0 - c * y0;
}
}
void scrie(int p)
{
if (p == 0) return;
printf("%d ", pos[p]);
scrie(last[p]);
}
void back(int p)
{
if (p > ct)
{
int mask1 = mask - mask0;
if (ok[mask0] && DP[mask] > DP[mask1] + 1)
{
DP[mask] = DP[mask1] + 1;
pos[mask] = b[mask0];
last[mask] = mask1;
}
return;
}
if (ok[mask0]) back(p + 1);
mask0 ^= list[p];
if (ok[mask0]) back(p + 1);
mask0 ^= list[p];
}
void solve()
{
int i;
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))]) continue;
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;
for (mask = 1; mask < 1 << n; ++mask)
{
ct = 0;
for (i = 0; i < n; ++i)
if (mask & (1 << i))
list[++ct] = (1 << i);
back(1);
}
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;
}