제출 #625786

#제출 시각아이디문제언어결과실행 시간메모리
625786d4xn메기 농장 (IOI22_fish)C++17
29 / 100
1099 ms231532 KiB
#pragma GCC optimize ("Ofast") //#pragma GCC target ("avx2") #include "fish.h" #include <bits/stdc++.h> using namespace std; //#define int long long #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]; map<tuple2, ll> dp[N]; //map<tuple<int, int, int>, ll> dp; // dp[i][j][k] = maximos peces que puedo conseguir // con las k primeras columnas donde // en la columna k+1 he subido i-1 // en la columna k+2 he subido j-1 ll mx(int curr, int h1, int h2) { if (curr == -1) return 0; tuple2 t = make_tuple(h1, h2); auto it = dp[curr].find(t); if (it != dp[curr].end()) return it->second; dp[curr][t] = mx(curr-1, 0, h1); it = dp[curr].find(t); if (curr+1 < n) { for (int h : c[curr+1]) { h++; ll cnt = 0; // ver si pillo los de la derecha if (curr+1 < n && h > max(h1, h2)) { if (curr+2 == n) { cnt += pre[curr+1][h-1] - pre[curr+1][h1-1]; //assert(pre[curr+1].count(h-1) && pre[curr+1].count(h1-1)); } else { cnt += pre[curr+1][h-1] - pre[curr+1][max(h1, h2)-1]; //assert(pre[curr+1].count(h-1) && pre[curr+1].count(max(h1, h2)-1)); } } // ver si pillo los de la izquierda if (curr-1 >= 0) { cnt += pre[curr-1][h-1]; //assert(pre[curr-1].count(h-1)); } // ver si he eliminado alguno de los que he pillado cnt -= pre[curr][min(h, h1)-1]; //assert(pre[curr].count(min(h, h1)-1)); it->second = max(it->second, cnt + mx(curr-1, h, h1)); } } if (curr-1 >= 0) { for (int h : c[curr-1]) { h++; ll cnt = 0; // ver si pillo los de la derecha if (curr+1 < n && h > max(h1, h2)) { if (curr+2 == n) { cnt += pre[curr+1][h-1] - pre[curr+1][h1-1]; //assert(pre[curr+1].count(h-1) && pre[curr+1].count(h1-1)); } else { cnt += pre[curr+1][h-1] - pre[curr+1][max(h1, h2)-1]; //assert(pre[curr+1].count(h-1) && pre[curr+1].count(max(h1, h2)-1)); } } // ver si pillo los de la izquierda if (curr-1 >= 0) { cnt += pre[curr-1][h-1]; //assert(pre[curr-1].count(h-1)); } // ver si he eliminado alguno de los que he pillado cnt -= pre[curr][min(h, h1)-1]; //assert(pre[curr].count(min(h, h1)-1)); it->second = max(it->second, cnt + mx(curr-1, h, h1)); } } 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; int mxX = 0; for (int i = 0; i < m; i++) { mxX = max(mxX, X[i]); w[X[i]][Y[i]] = W[i]; c[X[i]].push_back(Y[i]); } 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); if (w[0].count(i)) pre0[i] += w[0][i]; if (w[1].count(i)) pre1[i] += w[1][i]; } 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 == 2) return max(pre0[n-1], pre1[n-1]); 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, 0); }
#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...