There are a total of?NN?(1≤N≤1051≤N≤105) cows on the number line. The location of the?ii-th cow is given by?xixi?(0≤xi≤1090≤xi≤109), and the weight of the?ii-th cow is given by?yiyi?(1≤yi≤1041≤yi≤104).
At Farmer John's signal, some of the cows will form pairs such that
It's up to you to determine the range of possible sums of weights of the unpaired cows. Specifically,
The first line of input contains?TT,?NN, and?KK.In each of the following?NN?lines, the?ii-th contains?xixi?and?yiyi. It is guaranteed that?0≤x1<x2<?<xN≤1090≤x1<x2<?<xN≤109.
Please print out the minimum or maximum possible sum of weights of the unpaired cows.
2 5 2 1 2 3 2 4 2 5 1 7 2
6
In this example, cows?22?and?44?can pair up because they are at distance?22, which is at most?K=2K=2. This pairing is maximal, because cows?11?and?33?are at distance?33, cows?33?and?55?are at distance?33, and cows?11?and?55?are at distance?66, all of which are more than?K=2K=2. The sum of weights of unpaired cows is?2+2+2=62+2+2=6.
1 5 2 1 2 3 2 4 2 5 1 7 2
2
Here, cows?11?and?22?can pair up because they are at distance?2≤K=22≤K=2, and cows?44?and?55?can pair up because they are at distance?2≤K=22≤K=2. This pairing is maximal because only cow?33?remains. The weight of the only unpaired cow here is simply?22.
2 15 7 3 693 10 196 12 182 14 22 15 587 31 773 38 458 39 58 40 583 41 992 84 565 86 897 92 197 96 146 99 785
2470
The answer for this example is?693+992+785=2470693+992+785=2470.
Problem credits: Benjamin Qi
[/hide]
(Analysis by Andi Qu)
Let's call two adjacent cows "linked" if they are able to pair up with each other. We can split the cows up into chains where each pair of adjacent cows in a chain are linked, and no two cows in different chains are linked.
In each case below, we process each chain independently – let?nn?be the length of the current chain.
Case 1:?T=1T=1
For chains with an even number of cows, we can pair up all of them. For chains with an odd number of cows, we want to have exactly 1 unpaired cow. If we leave more than 1 cow unpaired, then we can split the chain into an odd-length suffix with 1 unpaired cow and an even-length prefix with all the other unpaired cows. Since the prefix has an even length, we can pair up all of its cows, which would result in a smaller sum of weights of unpaired cows.
We can thus iterate through each cow in odd-length chains, check whether it can be unpaired (removing it should not result in two odd-length chains), and finally, leave the least valuable cow unpaired.
This case can thus be solved in?O(N)O(N)?time.
Case 2:?T=2T=2
In this case, we should try to leave unpaired cows in both even- and odd-length chains. We can use dynamic programming to solve this in?O(NlogN)O(Nlog?N)?time.
Let?dp[i][j]dp[i][j]?be the maximum sum of values of unpaired cows if we only consider?ii?to?nn?cows in the current chain and there are?jj?unpaired ones. Let?ub[i]ub[i]?be the index of the leftmost cow to the right of cow?ii?that can be unpaired if cow?ii?is unpaired (or?n+1n+1?if it doesn't exist). We can compute?ub[i]ub[i]?using binary search.
If it's possible to leave cow?ii?unpaired with?jj?unpaired cows, then?dp[i][j]=max(dp[i+1][j],dp[ub[i]][j?1]+yi)dp[i][j]=max(dp[i+1][j],dp[ub[i]][j?1]+yi). Otherwise,?dp[i][j]=dp[i+1][j]dp[i][j]=dp[i+1][j].
Since we only care about the parity of the number of unpaired cows, we can drop the second dimension of the DP array. This allows us to compute the whole DP array in?O(NlogN)O(Nlog?N)?time (which can easily be reduced to?O(N)O(N)).
Andi's code:
#include <algorithm> #include <array> #include <iostream> #include <utility> #include <vector> using namespace std; const int INF = 1e9; int min_span_cost(vector<pair<int, int>>& span, int k) { int mn = INF; for (int i = 0; i < span.size(); i++) { if (!(i & 1) || span[i + 1].first - span[i - 1].first <= k) mn = min(mn, span[i].second); } return mn; } int max_span_cost(vector<pair<int, int>>& span, int k) { int n = span.size(); if (!n) return 0; vector<pair<int, int>> dp(n + 1); dp[n] = {0, -INF}; for (int i = n - 1; ~i; i--) { dp[i] = dp[i + 1]; int ub = upper_bound(span.begin(), span.end(), make_pair(span[i].first + k, INF)) - span.begin(); if (i == 0 || i == n - 1 || span[i + 1].first - span[i - 1].first <= k || !(n - i & 1)) dp[i].first = max(dp[i].first, dp[ub].second + span[i].second); if (i == 0 || i == n - 1 || span[i + 1].first - span[i - 1].first <= k || (n - i & 1)) dp[i].second = max(dp[i].second, dp[ub].first + span[i].second); } return (n & 1 ? dp[0].second : dp[0].first); } int main() { cin.tie(0)->sync_with_stdio(0); int t, n, k; cin >> t >> n >> k; int prev_x = 0, ans = 0; vector<pair<int, int>> curr_span; while (n--) { int x, y; cin >> x >> y; if (x - prev_x > k) { if (t == 1) { if (curr_span.size() & 1) ans += min_span_cost(curr_span, k); } else ans += max_span_cost(curr_span, k); curr_span.clear(); } curr_span.push_back({x, y}); prev_x = x; } if (t == 1) { if (curr_span.size() & 1) ans += min_span_cost(curr_span, k); } else ans += max_span_cost(curr_span, k); cout << ans; return 0; }
[/hide]
? 2025. All Rights Reserved. 沪ICP备2023009024号-1