Cod sursa(job #2011883)

Utilizator Mircea_DonciuDonciu Mircea Mircea_Donciu Data 17 august 2017 14:21:21
Problema Vanatoare Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.58 kb
# include <algorithm>
# include <cstdio>
using namespace std ;

typedef pair <int, int> PR ;
const char *FIN = "vanatoare.in", *FOU = "vanatoare.out" ;
const int MAX = 16 ;

# define V first
# define C second

PR A[MAX], best[1 << MAX] ;
int lun[1 << MAX] = {1}, dp[1 << MAX] ;
int N, T ;

int euclid (int A, int B) {
    return (B ? euclid (B, A % B) : A) ;
}

int doit (PR X, PR Y) {
    if ((X.C - Y.C) % euclid (X.V, Y.V)) return -1 ;
    if (X.V < Y.V) swap (X, Y) ;
    for (int i = 0; 1LL * i + X.C <= T; i += X.V) {
        if ((i + X.C) % Y.V == Y.C) {
            return i + X.C ;
        }
    }
    return -1 ;
}

# define CT i - (1 << j)

int main (void) {
    freopen (FIN, "r", stdin) ;

    scanf ("%d %d", &N, &T) ;
    for (int i = 0; i < N; ++i)
        scanf ("%d %d", &A[i].C, &A[i].V) ;
    sort (A, A + N) ;
    for (int i = 1, j; i < 1 << N; ++i) {
        for (j = N - 1; j + 1 && (i & 1 << j) == 0 ; --j) ;
        lun[i] = min (1LL + T, 1LL * lun[CT] * A[j].V / euclid (lun[CT], A[j].V)) ;

        if (dp[CT] == -1) {
            dp[i] = -1 ;
        } else {
            dp[i] = doit (make_pair (lun[CT], dp[CT]), A[j]) ;
        }

        best[i] = make_pair (N + 1, -1) ;
        for (j = i; j ; j = i & (j - 1)) {
            if (dp[j] != -1) {
                best[i] = min (best[i], make_pair (best[i - j].V + 1, j)) ;
            }
        }
    }
    freopen (FOU, "w", stdout) ;
    printf ("%d\n", best[(1 << N) - 1].V) ;
    for (int i = (1 << N) - 1; i ; i -= best[i].C)
        printf ("%d ", dp[ best[i].C ]) ;

}