제출 #626608

#제출 시각아이디문제언어결과실행 시간메모리
626608d4xn메기 농장 (IOI22_fish)C++17
32 / 100
1092 ms175604 KiB
#pragma GCC optimize ("Ofast") #include "fish.h" #include <bits/stdc++.h> using namespace std; #define ll long long #define vi vector<int> #define ii pair<int, int> #define vii vector<ii> #define tuple2 tuple<int, int> #define tuple3 tuple<int, int, int> const int N = 1e5; int n, m; vi c[N]; unordered_map<int, int> w[N]; unordered_map<int, ll> pre[N]; unordered_map<int, ll> dp[4][N]; ll mx(int curr, int h1, int state) { if (curr == -1) return 0; auto it = dp[state][curr].find(h1); if (it != dp[state][curr].end()) return it->second; if (state != 3) dp[state][curr][h1] = mx(curr-1, h1, 3); else dp[state][curr][h1] = mx(curr-1, 0, 2); it = dp[state][curr].find(h1); if (!state) { if (curr+1 < n) { for (int h : c[curr+1]) { h++; if (h >= h1) break; ll cnt = 0; // ver si pillo los de la izquierda if (curr-1 >= 0) { cnt += pre[curr-1][h-1]; } // ver si he eliminado alguno de los que he pillado cnt -= pre[curr][min(h, h1)-1]; it->second = max(it->second, cnt + mx(curr-1, h, 0)); } } if (curr-1 >= 0) { for (int h : c[curr-1]) { h++; if (h >= h1) break; ll cnt = 0; // ver si pillo los de la izquierda if (curr-1 >= 0) { cnt += pre[curr-1][h-1]; } // ver si he eliminado alguno de los que he pillado cnt -= pre[curr][min(h, h1)-1]; it->second = max(it->second, cnt + mx(curr-1, h, 0)); } } } else if (state == 1 || state == 2) { if (curr+1 < n) { for (int h : c[curr+1]) { h++; ll cnt = 0; // ver si pillo los de la izquierda if (curr-1 >= 0) { cnt += pre[curr-1][h-1]; } // ver si pillo los de la derecha if (h > h1 && curr+1 < n) { cnt += pre[curr+1][h-1] - pre[curr+1][h1-1]; } // ver si he eliminado alguno de los que he pillado cnt -= pre[curr][min(h, h1)-1]; if (h <= h1) it->second = max(it->second, cnt + mx(curr-1, h, 0)); else it->second = max(it->second, cnt + mx(curr-1, h, 1)); } } if (curr-1 >= 0) { for (int h : c[curr-1]) { h++; ll cnt = 0; // ver si pillo los de la izquierda if (curr-1 >= 0) { cnt += pre[curr-1][h-1]; } // ver si pillo los de la derecha if (h > h1 && curr+1 < n) { cnt += pre[curr+1][h-1] - pre[curr+1][h1-1]; } // ver si he eliminado alguno de los que he pillado cnt -= pre[curr][min(h, h1)-1]; if (h <= h1) it->second = max(it->second, cnt + mx(curr-1, h, 0)); else it->second = max(it->second, cnt + mx(curr-1, h, 1)); } } } else { if (curr+1 < n) { for (int h : c[curr+1]) { h++; ll cnt = 0; // ver si pillo los de la izquierda if (curr-1 >= 0) { cnt += pre[curr-1][h-1]; } // ver si pillo los de la derecha if (h > h1 && curr+1 < n) { cnt += pre[curr+1][h-1] - pre[curr+1][h1-1]; } it->second = max(it->second, cnt + mx(curr-1, h, 2)); } } if (curr-1 >= 0) { for (int h : c[curr-1]) { h++; ll cnt = 0; // ver si pillo los de la izquierda if (curr-1 >= 0) { cnt += pre[curr-1][h-1]; } // ver si pillo los de la derecha if (h > h1 && curr+1 < n) { cnt += pre[curr+1][h-1] - pre[curr+1][h1-1]; } it->second = max(it->second, cnt + mx(curr-1, h, 2)); } } } return it->second; } long long max_weights(int N, int M, std::vector<int> X, std::vector<int> Y, std::vector<int> W) { n = N; m = M; ll sum = 0; bool odd = 0; int mxX = 0; for (int i = 0; i < m; i++) { sum += W[i]; if (X[i]%2) odd = 1; mxX = max(mxX, X[i]); w[X[i]][Y[i]] = W[i]; c[X[i]].push_back(Y[i]); } if (!odd) return sum; if (mxX <= 1) { ll pre0[n], pre1[n]; for (int i = 0; i < n; i++) { pre0[i] = (i ? pre0[i-1] : 0); pre1[i] = (i ? pre1[i-1] : 0); auto it = w[0].find(i); if (it != w[0].end()) pre0[i] += it->second; it = w[1].find(i); if (it != w[1].end()) pre1[i] += it->second; } if (n == 2) return max(pre0[n-1], pre1[n-1]); ll ans = max(pre0[n-1], pre1[n-1]); for (int i = 0; i < n; i++) { ans = max(ans, pre0[i] + pre1[n-1] - pre1[i]); } if (n >= 3) return ans; } map<int, int> heights; for (int i = 0; i < n; i++) { pre[i][-1] = 0; for (int &h : c[i]) heights[h]++; if (i >= 3) { for (int &h : c[i-3]) { heights[h]--; if (!heights[h]) heights.erase(h); } } ll sum1 = 0; ll sum2 = 0; ll sum3 = 0; for (auto &[h, cnt] : heights) { auto it = w[i].find(h); if (it != w[i].end()) sum3 += it->second; pre[i][h] = sum3; if (i-1 >= 0) { it = w[i-1].find(h); if (it != w[i-1].end()) sum2 += it->second; pre[i-1][h] = sum2; } if (i-2 >= 0) { it = w[i-2].find(h); if (it != w[i-2].end()) sum1 += it->second; pre[i-2][h] = sum1; } } } return mx(n-1, 0, 2); }
#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...