#include "fish.h"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 305;
// dp[i][j][0] = best using columns 1..i, with column i "blocked" up to height j (pier length j)
// dp[i][j][1] = best using columns 1..i, taking fish in column i from bottom..j (caught by left neighbor)
// dp[i][j][2] = best using columns 1..i, taking fish in column i bottom..j and also some in column i-1
static ll dp[MAXN][MAXN][3];
static ll cost[MAXN][MAXN]; // cost[c][h] = sum of weights in column c up to height h (prefix)
ll max_weights(int N, int M, vector<int> X, vector<int> Y, vector<int> W) {
// reset
for (int i = 0; i <= N; ++i) {
for (int j = 0; j <= N; ++j) {
cost[i][j] = 0;
dp[i][j][0] = dp[i][j][1] = dp[i][j][2] = 0;
}
}
// collect fish per column and build prefix sums per column
vector<vector<pair<int,int>>> col(N+1);
for (int t = 0; t < M; ++t) {
int c = X[t] + 1; // 1-index columns
int r = Y[t] + 1; // 1-index rows
col[c].push_back({r, W[t]});
}
for (int c = 1; c <= N; ++c) {
sort(col[c].begin(), col[c].end());
int p = 0;
for (int h = 1; h <= N; ++h) {
cost[c][h] = cost[c][h-1];
while (p < (int)col[c].size() && col[c][p].first == h) {
cost[c][h] += col[c][p].second;
++p;
}
}
}
auto range_sum = [&](int c, int l, int r) -> ll {
if (l > r) return 0;
return cost[c][r] - cost[c][l-1];
};
// IMPORTANT: start from i = 2 so column 1 never "catches" from a non-existent left pier
for (int i = 2; i <= N; ++i) {
// --- dp[i][j][2]: take in col i (up to j) and also some in col i-1 ---
// For a chosen left pier height k at col (i-1):
// - col i contributes cost[i][min(j,k)] (left pier must reach that row)
// - col i-1 contributes range (k, j] (own pier doesn't cover, right pier j catches)
// dp contribution from col <= i-2 is independent of k -> take best0 = max_t dp[i-2][t][0]
ll best0 = 0;
if (i >= 2) {
for (int t = 0; t <= N; ++t) best0 = max(best0, dp[i-2][t][0]);
}
for (int j = 0; j <= N; ++j) {
ll best_k = 0; // we maximize over k
for (int k = 0; k <= N; ++k) {
ll take_i = cost[i][min(j, k)];
ll take_im1 = range_sum(i-1, k+1, j);
best_k = max(best_k, take_i + take_im1);
}
dp[i][j][2] = max(dp[i][j][2], best0 + best_k);
}
// --- dp[i][j][1]: take in col i from bottom..j, caught by left neighbor col (i-1) ---
// Require left pier height k >= j. We extend from dp[i-1][k][0].
for (int j = 0; j <= N; ++j) {
for (int k = j; k <= N; ++k) {
dp[i][j][1] = max(dp[i][j][1], dp[i-1][k][0] + cost[i][j]);
}
}
// --- dp[i][j][0]: block up to j in col i ---
// Either:
// 1) we previously blocked col (i-1) up to k, and now catch (i-1)'s fish in (k, j] via right pier j, or
// 2) carry over a configuration where col (i-1) already took (states 1 or 2) up to the same j.
for (int j = 0; j <= N; ++j) {
// case (1): catch from left column thanks to current right pier j
for (int k = 0; k <= j; ++k) {
dp[i][j][0] = max(dp[i][j][0],
dp[i-1][k][0] + range_sum(i-1, k+1, j));
}
// case (2): carry over
dp[i][j][0] = max(dp[i][j][0], dp[i-1][j][1]);
dp[i][j][0] = max(dp[i][j][0], dp[i-1][j][2]);
}
// Monotonicity: blocking more (bigger j) cannot hurt
for (int j = N-1; j >= 0; --j) {
dp[i][j][0] = max(dp[i][j][0], dp[i][j+1][0]);
}
}
// Answer is the best at column N over all heights and states
ll ans = 0;
if (N == 1) return 0; // cannot catch anything with only one column
for (int j = 0; j <= N; ++j) {
ans = max(ans, dp[N][j][0]);
ans = max(ans, dp[N][j][1]);
// ans = max(ans, dp[N][j][2]);
}
return ans;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |