# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1130935 | belgianbot | Catfish Farm (IOI22_fish) | C++20 | 0 ms | 0 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,int>>(2));
return dp(0, -10, false, -1);
}