Cod sursa(job #1710514)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 29 mai 2016 09:57:55
Problema Sate2 Scor 100
Compilator cpp Status done
Runda Arhiva ICPC Marime 2.13 kb
#include <bits/stdc++.h>

using namespace std;

constexpr int MAX_N = 3000;
constexpr int MAX_K = 4;

struct heapCmp {
  inline bool operator () (const vector <int> &A, const vector <int> &B) const {
    size_t i = 0;
    while ((i < A.size()) && (A[i] == B[i]))
      i += 1;
    return A[i] < B[i];
  }
};

int item[MAX_N];

bool greedy1(const int n, const int k) {
  int m_size[MAX_K];

  sort(item, item + n);

  const int tLimit = 4000000 / n;

  int t = 0;
  int j;
  do {
    for (int i = 0; i < k; i += 1)
      m_size[i] = 0;
    for (int i = n - 1; i >= 0; i -= 1) {
      int bestSack = 0;
      for (int j = 1; j < k; j += 1)
        if (m_size[j] < m_size[bestSack])
          bestSack = j;
      m_size[bestSack] += item[i];
    }
    j = 1;
    while ((j < k) && (m_size[j] == *m_size))
      j += 1;
    t += 1;
  } while ((t <= tLimit) && (j != k) && next_permutation(item, item + n));

  return j == k;
}

bool greedy2(const int n, const int k) {
  priority_queue <vector <int>, vector <vector <int>>, heapCmp> Heap;
  vector <int> C;
  for (int i = 0; i < n; i += 1) {
    C.clear();
    C.push_back(item[i]);
    for (int j = 1; j < k; j += 1)
      C.push_back(0);
    Heap.push(C);
  }
  while (Heap.size() > 1) {
    vector <int> A = Heap.top(); Heap.pop();
    vector <int> B = Heap.top(); Heap.pop();
    C.clear();
    for (int i = 0; i < k; i += 1)
      C.push_back(A[i] + B[k - i - 1]);
    sort(C.begin(), C.end(), greater <int>());
    for (int i = 0; i < k; i += 1)
      C[i] -= C[k - 1];
    Heap.push(C);
  }
  C = Heap.top();
  int i = 0;
  while ((i < k) && (!C[i]))
    i += 1;
  return (i == k);
}

int main() {
  ifstream fin("sate2.in");
  ofstream fout("sate2.out");
  fin.tie(0);
  ios_base::sync_with_stdio(0);

  int numTests; fin >> numTests;

  while (numTests--) {
    int n, m, k; fin >> n >> m >> k;
    for (int i = 0; i < n; i += 1)
      fin >> item[i];
    if ((n < k) || (m % k) || (!greedy1(n, k) && !greedy2(n, k))) {
      fout << "NU\n";
    } else {
      fout << "DA\n";
    }
  }
  fin.close();
  fout.close();

  return 0;
}