Cod sursa(job #2706223)

Utilizator retrogradLucian Bicsi retrograd Data 14 februarie 2021 12:36:19
Problema Ghiozdan Scor 100
Compilator cpp-64 Status done
Runda Lista lui wefgef Marime 1.31 kb
#include <bits/stdc++.h>

using namespace std;
const int MAXW = 200;

struct Queue {
  deque<int> d;
  void Push(int x) {
    while (d.size() && d.back() > x) 
      d.pop_back();
    d.push_back(x);
  }
  void Pop(int x) {
    if (d.front() == x)
      d.pop_front();
  }
  int Min() { return d.front(); }
};

int main() {
  ifstream cin("ghiozdan.in");
  ofstream cout("ghiozdan.out");

  int n, g; cin >> n >> g;
  vector<int> freq(MAXW + 1, 0);
  for (int i = 0; i < n; ++i) {
    int x; cin >> x; freq[x] += 1;
  }

  vector<int> dp(g + 1, 1e9), ndp(dp);
  Queue Q;
  dp[0] = 0;
  for (int w = 1; w <= MAXW; ++w) {
    int have = freq[w];
    if (have == 0) continue;
    ndp = dp;
    for (int rem = 0; rem < w; ++rem) {
      Q.d.clear();
      for (int div = 0; div * w + rem <= g; ++div) {
        int pos = div * w + rem;
        if (div > 0)
          ndp[pos] = min(ndp[pos], Q.Min() + div);
        Q.Push(dp[pos] - div);
        if (div >= have) 
          Q.Pop(dp[pos - have * w] - (div - have));
      }
    }
    dp = ndp;
  }

  for (int gg = g; gg >= 0; --gg) {
    int cnt = dp[gg];
    if (cnt <= n) {
      cout << gg << " " << cnt << endl;
      while (cnt--) {
        int w = 0;
        while (dp[gg] != cnt || freq[w] == 0) ++w, --gg;
        cout << w << '\n';
        --freq[w];
      }
      return 0;
    }
  }
}