Cod sursa(job #171769)

Utilizator dominoMircea Pasoi domino Data 5 aprilie 2008 00:49:13
Problema Vanatoare Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.42 kb
#include <stdio.h>
#include <algorithm>

using namespace std;

#define MAX_N 16
#define FIN "vanatoare.in"
#define FOUT "vanatoare.out"
#define f first
#define s second
#define mp make_pair
#define ll long long

int N, T, lcm[1<<MAX_N], res[1<<MAX_N];
pair<int, int> A[MAX_N], bst[1<<MAX_N];

int gcd(int a, int b)
{
    return !b ? a : gcd(b, a%b);
}

int solve(pair<int, int> a, pair<int, int> b)
{
    int ret;

    if ((a.s-b.s) % gcd(a.f, b.f) != 0) return -1;
    if (a.f < b.f) swap(a, b);
    for (ret = 0; (ll)ret+a.s <= T; ret += a.f)
        if ((ret+a.s)%b.f == b.s) return ret+a.s;
    return -1;
}

int main(void)
{
    int i, j;

    freopen(FIN, "r", stdin);
    freopen(FOUT, "w", stdout);

    scanf("%d %d", &N, &T);
    for (i = 0; i < N; ++i)
        scanf("%d %d", &A[i].s, &A[i].f);

    sort(A, A+N);
    for (lcm[0] = i = 1; i < (1<<N); ++i)
    {
        for (j = N-1; j >= 0 && !(i&(1<<j)); --j);
        lcm[i] = min((ll)T+1, (ll)lcm[i-(1<<j)]*A[j].f/gcd(lcm[i-(1<<j)], A[j].f));

        if (res[i-(1<<j)] == -1) 
            res[i] = -1;
        else
            res[i] = solve(mp(lcm[i-(1<<j)], res[i-(1<<j)]), mp(A[j].f, A[j].s));

        bst[i] = mp(N+1, -1);
        for (j = i; j > 0; j = i&(j-1))
            if (res[j] != -1) bst[i] = min(bst[i], mp(bst[i-j].f+1, j));
    }
    printf("%d\n", bst[(1<<N)-1].f);
    for (i = (1<<N)-1; i != 0; i -= bst[i].s)
        printf("%d ", res[bst[i].s]);


    return 0;
}