Cod sursa(job #2500050)

Utilizator MiricaMateiMirica Matei MiricaMatei Data 27 noiembrie 2019 10:29:04
Problema Vanatoare Scor 5
Compilator cpp-64 Status done
Runda guritza Marime 1.8 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 16;
const int MAXS = (1 << MAXN);

int sePoate[MAXS + 5];
int dp[MAXS + 5];

int v[MAXN + 5], c[MAXN + 5];
long long a[MAXN + 5], b[MAXN + 5];
int from[MAXS + 5], cn[MAXS + 5];

int main() {
  freopen("vanatoare.in", "r", stdin);
  freopen("vanatoare.out", "w", stdout);

  int n, t;
  scanf("%d%d", &n, &t);
  for (int i = 1; i <= n; ++i)
    scanf("%d%d", &c[i], &v[i]);
  sePoate[0] = 1;
  for (int i = 1; i < (1 << n); ++i) {
    sePoate[i] = -1;
    int w;
    for (w = 0; w < n; ++w)
      if (i & (1 << w))
        break;
    int s = i ^ (1 << w);
    w++;
    if (s == 0) {
      sePoate[i] = c[w];
      a[i] = v[w];
      b[i] = c[w];
      continue;
    }
    if (sePoate[s] == -1)
      continue;
    if (abs(b[s] - c[w]) % __gcd((int)a[s], v[w]) != 0)
      continue;
    int x = b[s];
    int y = c[w];
    for (int j = 0; j < 800; ++j) {
      if (x == y)
        break;
      if (x < y) {
        x += a[s];
        if (x > t)
          break;
      } else {
        y += v[w];
        if (y > t)
          break;
      }
    }
    if (x == y) {
      sePoate[i] = x;
      b[i] = x;
      a[i] = 1LL * a[s] * v[w] / __gcd((int)a[s], v[w]);
    }
  }

  dp[0] = 0;
  for (int i = 1; i < (1 << n); ++i) {
    dp[i] = 1e9;
    if (sePoate[i] != -1) {
      dp[i] = 1;
      from[i] = 0;
      cn[i] = b[i];
    }
    for (int j = (i - 1) & i; j > 0; j = (j - 1) & i) {
      if (sePoate[j] != -1 && dp[i] > dp[i ^ j] + 1) {
        dp[i] = dp[i ^ j] + 1;
        from[i] = i ^ j;
        cn[i] = b[j];
      }
    }
  }

  printf("%d\n", dp[(1 << n) - 1]);
  int s = (1 << n) - 1;
  for (int i = dp[s]; i > 0; --i) {
    printf("%d ", cn[s]);
    s = from[s];
  }

  return 0;
}