Submission #1130936

#TimeUsernameProblemLanguageResultExecution timeMemory
1130936belgianbotCatfish Farm (IOI22_fish)C++20
0 / 100
1100 ms129812 KiB
#include "fish.h"

#include <bits/stdc++.h>

using namespace std;

struct fish {
  int x, y, w;
};
int M, N;
vector<fish> f;
vector<int> idx;
vector<vector<long long>> pref;
vector<vector<map<int,long long>>> memo;

long long prefix(int n, int l, int r) {
  if (r < l) return 0;
  if (l <= 0) return pref[n][r];
  return pref[n][r] - pref[n][l-1];
}
bool comp2 (const fish &a, const fish &b) {
  if (a.x < b.x) return true;
  if (a.x == b.x && a.y < b.y) return true;
  if (a.x == b.x && a.y == b.y && a.w < b.w) return true;
  return false;
}
bool nothingLeft(int i) {
  int idx = lower_bound(f.begin(), f.end(), fish({f[i].x-1, -1, -1}), comp2) - f.begin();
  if (f[idx].x == f[i].x || (f[idx].x == f[i].x-1 && f[idx].y > f[i].y)) return true;
  return false;
}
long long dp(int i, int curr, bool already, int higher) {
  if (i >= M) return 0;

  if (f[i].x == curr + 1) {
    int ind = lower_bound(f.begin() + i, f.end(), fish({curr + 1, higher + 1, -1}), comp2) - f.begin();
    return dp(ind, curr + 1, false, -1);
  }
  else if (f[i].x > curr + 1) {
    curr = f[i].x;
    already = false;
    higher = -1;
  }

  if (memo[i][already].count(higher)) return memo[i][already][higher];
  long long take = -1;
  if (f[i].x && nothingLeft(i)) take = dp(i + 1, curr, true, f[i].y) + f[i].w;
  else if (f[i].x < N - 1) {
    take = dp(i + 1, curr, true, f[i].y) + f[i].w;
    if (!already) take -= prefix(f[i].x, 0, idx[i] - 1);
  }

  long long notake = -1;
  if (!already) notake = dp(i + 1, curr, false, f[i].y) + prefix(f[i].x, idx[i] - 1, idx[i]);
  else notake = dp(i + 1, curr, true, higher);

  return memo[i][already][higher] = max(take, notake);
}
long long max_weights(int NN, int MM, vector<int> X, vector<int> Y,vector<int> W) {
  ios::sync_with_stdio(false);
  M = MM, N = NN;
  f.resize(M);
  for (int i = 0; i < M; i++) f[i] = fish({X[i], Y[i], W[i]});

  sort(f.begin(), f.end(), comp2);

  pref.resize(N); idx.resize(M);
  for (int i = 0; i < M; i++) {
    idx[i] = (int)(pref[f[i].x].size());
    pref[f[i].x].push_back(0);
    if (f[i].x) {
      int ind = lower_bound(f.begin(), f.end(), fish({f[i].x-1, f[i].y, -1}), comp2) - f.begin();
      if (f[ind].x == f[i].x - 1) pref[f[i].x-1][idx[ind]] += f[i].w;
    }
  }
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < int(pref[i].size()); j++) {
      if (j) pref[i][j] += pref[i][j-1];
    }
  }
  memo.resize(M, vector<map<int,long long>>(2));

  return dp(0, -10, false, -1);
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...