Submission #1362905

#TimeUsernameProblemLanguageResultExecution timeMemory
1362905SmuggingSpunSki 2 (JOI24_ski2)C++20
100 / 100
264 ms1940 KiB
#include<bits/stdc++.h>
#define taskname "C"
using namespace std;
typedef long long ll;
template<class T>void minimize(T& a, T b){
  if(a > b){
    a = b;
  }
}
const int lim = 305;
int n, k, h[lim], c[lim];
namespace sub1{
  void solve(){
    int idm = 1;
    for(int i = 2; i <= n; i++){
      if(h[i] < h[idm] || (h[i] == h[idm] && c[i] < c[idm])){
        idm = i;
      }
    }
    ll ans = 0;
    for(int i = 1; i <= n; i++){
      if(i != idm && h[i] == h[idm]){
        ans += k;
        h[i]++;
      }
    }
    vector<int>p(n);
    iota(p.begin(), p.end(), 1);
    sort(p.begin(), p.end(), [&] (int i, int j){
      return h[i] > h[j];
    });
    vector<bool>nuse(n, true);
    for(int i = n - 2; i > -1; i--){
      bool flag = true;
      for(int j = i + 1; j < n; j++){
        if(h[p[j]] < h[p[i]] && nuse[p[j]]){
          nuse[p[j]] = flag = false;
          break;
        }
      }
      if(flag){
        int id = idm;
        for(int j = i + 1; j < n; j++){
          if(h[p[j]] < h[p[i]] && c[p[j]] < c[id]){
            id = p[j];
          }
        }
        ans += c[id];
      }
    }
    cout << ans;
  }
}
const ll INF = 1e18;
namespace sub34{
  const int lim = 42;
  const int LIM = lim << 1;
  ll f[LIM][lim][lim];
  int cnt[LIM], min_cost[LIM];
  ll dp(int pos, int bef, int cuse){
    if(pos == LIM){
      return ll(max(0, bef - cuse)) * min_cost[LIM - 1];
    }
    ll& ans = f[pos][bef][cuse];
    if(ans != -1){
      return ans;
    }
    ans = INF;
    bef += cnt[pos];
    for(int i = 0; i <= min(cuse, bef); i++){
      for(int j = 0; i + j <= bef; j++){
        minimize(ans, ll(j) * min_cost[pos - 1] + ll(k) * (bef - i - j) + dp(pos + 1, bef - i - j, cuse + j));
      }
    }
    return ans;
  }
  void solve(){
    int idm = 1;
    for(int i = 2; i <= n; i++){
      if(h[i] < h[idm] || (h[i] == h[idm] && c[i] < c[idm])){
        idm = i;
      }
    }
    ll init_delta = 0;
    for(int i = 1; i <= n; i++){
      if(i != idm && h[i] == h[idm]){
        init_delta += k;
        h[i]++;
      }
    }
    memset(min_cost, 0x3f, sizeof(min_cost));
    memset(cnt, 0, sizeof(cnt));
    for(int i = 1; i <= n; i++){
      minimize(min_cost[h[i]], c[i]);
      cnt[h[i]]++;
    }
    for(int i = 1; i < LIM; i++){
      minimize(min_cost[i], min_cost[i - 1]);
    }
    memset(f, -1, sizeof(f));
    cout << dp(1, 0, 1) + init_delta;
  }
}
namespace sub256{
  const int lim = 302;
  const int LIM = 3000;
  int cnt[LIM], min_cost[LIM];
  ll f[lim][lim], pfm[lim][lim];
  void solve(){
    int idm = 1;
    for(int i = 2; i <= n; i++){
      if(h[i] < h[idm] || (h[i] == h[idm] && c[i] < c[idm])){
        idm = i;
      }
    }
    for(int i = 1, mih = h[idm]; i <= n; i++){
      h[i] -= mih;
    }
    ll init_delta = 0;
    map<int, int>big_cnt;
    for(int i = 1; i <= n; i++){
      if(i != idm && h[i] == h[idm]){
        init_delta += k;
        h[i]++;
      }
      big_cnt[h[i]]++;
    }
    vector<int>comp;
    for(int i = 1; i <= n; i++){
      for(int j = big_cnt[h[i]] * 5; j > -1; j--){
        comp.push_back(h[i] + j);
      }
      big_cnt[h[i]] = -1;
    }
    sort(comp.begin(), comp.end());
    comp.resize(unique(comp.begin(), comp.end()) - comp.begin());
    while(comp.size() <= LIM){
      comp.push_back(comp.back() + 1);
    }
    memset(min_cost, 0x3f, sizeof(min_cost));
    memset(cnt, 0, sizeof(cnt));
    for(int i = 1; i <= n; i++){
      cnt[h[i] = lower_bound(comp.begin(), comp.end(), h[i]) - comp.begin()]++;
      minimize(min_cost[h[i]], c[i]);
    }
    for(int i = 1; i < LIM; i++){
      minimize(min_cost[i], min_cost[i - 1]);
    }
    for(int bef = 0; bef <= n; bef++){
      for(int cuse = 0; cuse <= n; cuse++){
        f[bef][cuse] = ll(max(0, bef - cuse)) * min_cost[LIM - 1];
      }
    }
    for(int pos = LIM - 1; pos > 0; pos--){
      for(int sum = 0; sum <= n; sum++){
        ll cmin = INF;
        for(int bef = 0; bef <= sum; pfm[sum][bef++] = cmin){
          minimize(cmin, ll(k) * (comp[pos + 1] - comp[pos]) * bef + ll(min_cost[pos - 1]) * (lim - bef) + f[bef][sum - bef]);
        }
      }
      for(int bef = cnt[pos]; bef <= n; bef++){
        for(int cuse = 0; bef + cuse <= n; cuse++){
          int nbef = bef - min(bef, cuse);
          f[bef - cnt[pos]][cuse] = min(pfm[bef + cuse][bef] - ll(lim - bef) * min_cost[pos - 1], pfm[nbef + cuse][nbef] - ll(lim - nbef) * min_cost[pos - 1]);
        }
      }
    }
    cout << f[0][1] + init_delta;
  }
}
int main(){
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	if(fopen(taskname".inp", "r")){
		freopen(taskname".inp", "r", stdin);
	}
  cin >> n >> k;
  for(int i = 1; i <= n; i++){
    cin >> h[i] >> c[i];
  }
  if(k >= 100000 && *max_element(h + 1, h + n + 1) <= 300 && *max_element(c + 1, c + n + 1) <= 100){
    sub1::solve();
  }
  else if(n <= 40 && *max_element(h + 1, h + n + 1) <= 40){
    sub34::solve();
  }
  else{
    sub256::solve();
  }
}

Compilation message (stderr)

Main.cpp: In function 'int main()':
Main.cpp:174:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  174 |                 freopen(taskname".inp", "r", stdin);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...