제출 #1120307

#제출 시각아이디문제언어결과실행 시간메모리
1120307Nonoze메기 농장 (IOI22_fish)C++17
15 / 100
1090 ms431660 KiB
#include "fish.h" #include <bits/stdc++.h> using namespace std; #ifndef _IN_LOCAL #define dbg(...) #endif #define endl '\n' #define endlfl '\n' << flush #define quit(x) return (void)(cout << x << endl) template<typename T> void read(T& x) { cin >> x;} template<typename T1, typename T2> void read(pair<T1, T2>& p) { read(p.first), read(p.second);} template<typename T> void read(vector<T>& v) { for (auto& x : v) read(x); } template<typename T1, typename T2> void read(T1& x, T2& y) { read(x), read(y); } template<typename T1, typename T2, typename T3> void read(T1& x, T2& y, T3& z) { read(x), read(y), read(z); } template<typename T1, typename T2, typename T3, typename T4> void read(T1& x, T2& y, T3& z, T4& zz) { read(x), read(y), read(z), read(zz); } template<typename T> void print(vector<T>& v) { for (auto& x : v) cout << x << ' '; cout << endl; } #define sz(x) (int)(x.size()) #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define pb push_back #define mp(a, b) make_pair(a, b) #define fi first #define se second #define cmin(a, b) a = min(a, b) #define cmax(a, b) a = max(a, b) #define YES cout << "YES" << endl #define NO cout << "NO" << endl #define QYES quit("YES") #define QNO quit("NO") #define int long long #define double long double const int inf = numeric_limits<int>::max() / 4; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); const int MOD = 1e9+7, LOG=20; int n; vector<vector<pair<int, int>>> pref, is; vector<vector<vector<vector<vector<int>>>>> memo; vector<unordered_map<signed, unordered_map<signed, int>>> isnxt; int calc(int x, int l, int r) { if (l>r || x>=n || x<0) return 0; if (isnxt[x][l].count(r)) return isnxt[x][l][r]; auto lb=lower_bound(all(pref[x]), mp(r, -1LL)); if (lb->fi!=r) { if (lb==pref[x].begin()) return 0; lb--; } if (l==0) return isnxt[x][l][r]=lb->se; int ans=lb->se; lb=lower_bound(all(pref[x]), mp(l, -1LL)); if (lb==pref[x].begin()) return isnxt[x][l][r]=ans; lb--; return isnxt[x][l][r]=ans-lb->se; } int dp(int i, int j, int nb, bool before, bool taking) { if (nb>=3 || i>=n) return 0; if (sz(memo[i])<=j) memo[i].resize(j+1); if (sz(memo[i][j])<=nb) memo[i][j].resize(nb+1); if (sz(memo[i][j][nb])<=before) memo[i][j][nb].resize(before+1); if (sz(memo[i][j][nb][before])<=taking) memo[i][j][nb][before].resize(taking+1, -1); if (memo[i][j][nb][before][taking]!=-1) return memo[i][j][nb][before][taking]; int ans=0; if (taking) { if (nb==2) { cmax(ans, dp(i+1, j, 0, 0, 0) + calc(i-1, 0, is[i][j].fi-1) + calc(i+1, 0, is[i][j].fi-1)); if (j+1<sz(is[i])) cmax(ans, dp(i, j+1, 2, 0, 1)); } else if (nb==1) { cmax(ans, dp(i+1, j, 0, 0, 0) + calc(i+1, 0, is[i][j].fi-1)); if (before && j) cmax(ans, dp(i, j-1, 1, 1, 1)); else if (!before && j+1<sz(is[i])) cmax(ans, dp(i, j+1, 1, 0, 1)+calc(i-1, is[i][j].fi, is[i][j+1].fi-1)); } else { if (i+1<n) { int res=dp(i+2, j, 1, 0, 0); int empl=lower_bound(all(is[i+1]), mp(is[i][j].fi, -1LL))-is[i+1].begin(), clc=pref[i+1][empl].se-is[i+1][empl].se; if (!before) cmax(res, dp(i+1, empl, 0, 0, 1) - clc + (before?0:calc(i, is[i][j].fi, is[i+1][empl].fi-1))); else if (empl) cmax(res, dp(i+1, empl-1, 0, 1, 1) + is[i][empl].se - clc); // cout << res << ' ' << i << ' ' << j << ' ' << calc(i, is[i][j].fi, is[i+1][empl].fi-1) << endl; cmax(ans, res + calc(i+1, 0, is[i][j].fi-1)); } if (before && j) cmax(ans, dp(i, j-1, 0, 1, 1)+is[i][j-1].se); else if (!before && j+1<sz(is[i])) cmax(ans, dp(i, j+1, 0, 0, 1) + calc(i-1, is[i][j].fi, is[i][j+1].fi-1)); } } else { cmax(ans, dp(i+1, j, nb+1, 0, 0)); if (nb==0) { int empl=lower_bound(all(is[i]), mp(is[i-1][j].fi, -1LL))-is[i].begin(), clc=pref[i][empl].se-is[i][empl].se; cmax(ans, dp(i, empl, 0, 0, 1) - clc + calc(i-1, is[i-1][j].fi, is[i][empl].fi-1)); if (empl) cmax(ans, dp(i, empl-1, 0, 1, 1) + is[i][empl].se - clc); // cout << i << ' ' << empl << ' ' << clc << ' ' << dp(i, empl, 0, 1, 1) - clc << endl; } else if (nb==1) { int empl=0; if (i-2>=0) empl=lower_bound(all(is[i]), mp(is[i-2][j].fi, -1LL))-is[i].begin(); cmax(ans, dp(i, empl, 1, 0, 1)); if (empl) cmax(ans, dp(i, empl-1, 1, 1, 1)); } else { cmax(ans, dp(i, 0, nb, 0, 1)); } } // cout << i << ' ' << j << ' ' << nb << ' ' << before << ' ' << taking << ' ' << ans << endl; return memo[i][j][nb][before][taking]=ans; } int max_weights(signed N, signed m, vector<signed> x, vector<signed> y, vector<signed> w) { n=N; pref.resize(n), is.resize(n), memo.resize(n); isnxt.resize(n); for (int i=0; i<m; i++) { is[x[i]].pb({y[i], w[i]}); } for (int i=0; i<n; i++) { sort(all(is[i])); is[i].pb({n, 0}); int sm=0; for (auto [j, x]: is[i]) { sm+=x; pref[i].pb({j, sm}); } } return dp(0, 0, 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...