Submission #625762

#TimeUsernameProblemLanguageResultExecution timeMemory
625762d4xnCatfish Farm (IOI22_fish)C++17
14 / 100
1078 ms62200 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 = 300; 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; for (int i = 0; i < m; i++) { w[X[i]][Y[i]] = W[i]; c[X[i]].push_back(Y[i]); } map<int, int> heights; for (int i = 0; i < n; i++) { pre[i][-1] = 0; //sort(c[i].begin(), c[i].end()); 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) { if (w[i].count(h)) sum3 += w[i][h]; pre[i][h] = sum3; if (i-1 >= 0) { if (w[i-1].count(h)) sum2 += w[i-1][h]; pre[i-1][h] = sum2; } if (i-2 >= 0) { if (w[i-2].count(h)) sum1 += w[i-2][h]; 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...