Cod sursa(job #2706216)

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

using namespace std;
const int MAXW = 19;

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> cnt(MAXW + 1, 0);
  for (int i = 0; i < n; ++i) {
    int x; cin >> x; cnt[x] += 1;
  }

  vector<vector<int>> dp(MAXW + 1, vector<int>(g + 1, 1e9));
  Queue Q;
  dp[0][0] = 0;
  for (int w = 1; w <= MAXW; ++w) {
    int have = cnt[w];
    dp[w] = dp[w - 1];
    if (have == 0) continue;
    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)
          dp[w][pos] = min(dp[w][pos], Q.Min() + div);
        Q.Push(dp[w - 1][pos] - div);
        if (div >= have) 
          Q.Pop(dp[w - 1][pos - have * w] - (div - have));
      }
    }
  }
  
  for (int gg = g; gg >= 0; --gg) {
    int cnt = dp[MAXW][gg];
    if (cnt <= n) {
      cout << gg << " " << cnt << endl;
      for (int i = MAXW; i; --i) {
        while (dp[i - 1][gg] != cnt) {
          cout << i << '\n';
          gg -= i; cnt -= 1;
        }
      }
      return 0;
    }
  }
}