Submission #1257271

#TimeUsernameProblemLanguageResultExecution timeMemory
1257271wheelertHacker (BOI15_hac)C++20
20 / 100
1096 ms420 KiB
#include <iostream> #include <vector> #include <deque> using namespace std; // Problem Statement: // You are playing a game against an opponent on a connected ring of nodes 1 ... n where node 1 is connected to // You first get to choose where to start, any node // Then your opponent gets to choose any node where to start // // Then you and your opponent alternate turns where you may either capture any node not captured by your opponen // Each node has a value given to you // You each take turns until no one can capture any more nodes // assume your oppoenent plays optimally // // what is the maximum score you can obtain assuming your opponent plays optimally. // // // int naive_solution(vector<int> const& arr) { int N = arr.size(); int num_window = ( N + 1 ) / 2; // for each spot // there are (num_window) subranges of length (num_window) containing node[i] // villain can force us to choose have any of these, so playing // optimally he will choose the one that minimizes our score // static constexpr int INF = 1'000'000'000; vector<int> min_answer_per_node(N, INF); // naive solution for (int i = 0; i < N; ++i) { for (int j = 0; j < num_window; ++j) { int subrange_sum = 0; int subrange_start = i + j - num_window + 1; for (int k = 0; k < num_window; ++k) { subrange_sum += arr[(subrange_start + k + N) % N]; } min_answer_per_node[i] = std::min(min_answer_per_node[i], subrange_sum); } } int answer = min_answer_per_node[0]; for (int i = 1; i < N; ++i) answer = std::max(min_answer_per_node[i], answer); return answer; } int optimal_solution(vector<int> const& arr) { int N = arr.size(); int num_window = ( N + 1 ) / 2; // invariant - (index, val) in window min is always sorted in increasing order of // - querying the min can always be done by accessing front() // deque<pair<int, int>> window_min{}; auto insert = [&](int index, int val) { while (window_min.size() > 0 && window_min.back().second > val) window_min.pop_back(); window_min.emplace_back( index, val ); while (window_min.size() > 0 && window_min.front().first <= index - num_window) window_min.pop_front(); }; static constexpr int INF = 1'000'000'000; vector<int> min_answer_per_node(N, INF); int subrange_sum = 0; for (int k = 0; k < num_window; ++k) { subrange_sum += arr[(0 - num_window + 1 + k + N) % N]; } for (int j = 0; j < num_window; ++j) { insert(j - num_window + 1, subrange_sum); int subrange_start = (j - num_window + 1 + N) % N; int subrange_end = j; //std::cout << "start: " << subrange_start << " end: " << subrange_end << std::endl; //std::cout << subrange_sum << endl; subrange_sum += arr[(j + 1 + N) % N]; subrange_sum -= arr[(j - num_window + 1 + N) % N]; } for (int i = 0; i < N ; ++i) { min_answer_per_node[i] = window_min.front().second; subrange_sum += arr[(i + num_window + N) % N]; subrange_sum -= arr[i]; insert(i + 1, subrange_sum); } int answer = 0; for (int i = 0; i < N; ++i) answer = std::max(min_answer_per_node[i], answer); return answer; } // test driver int main() { int N; cin >> N; vector<int> arr(N); for (int i = 0; i < N; ++i) cin >> arr[i]; std::cout << naive_solution(arr) << std::endl; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...