Goldilocks and N cows
You may have heard the classic story about Goldilocks and three bears.
However, little is known that Goldilocks eventually became a farmer.
On her farm, there are $N $cows in her cowshed.
Unfortunately, her cows are quite sensitive to temperature.
For cows $I $, the temperature that makes them feel comfortable is $A_{i}…B_{i}$.
If Goldilocks sets the temperature of the barn thermostat to $T $to $T < a_ {i} $the cow will feel cold and produce $X $units of milk.
If she sets the thermostat temperature $t $to $A_{i} \leq T \leq B_{i} $, the cow will feel comfortable and produce $Y $units of milk.
If she sets the thermostat temperature $T $to $T > B_ {i} $, the cow will feel hot and produce $Z $units of milk.
As expected, $Y $is always greater than $X $and $Z $.
Given $X $, $Y $, $Z $and the comfortable temperature range for each cow, please calculate the maximum milk yield that can be obtained by reasonably setting the thermostat temperature.
The thermostat temperature can be set to any integer.
Input format
The first line contains four integers $N $, $X $, $Y $, $Z $.
The next $N $line contains two integers $A_{i} $and $B_{i}$.
Output format
Output the maximum milk yield available.
Data range
$1 \leq N \leq 20000$,
$0 \leq X, Y, Z \leq 1000$,
$0 \leq A_{i} \leq B_{i} \leq {10}^{9}$
Input sample:
4 7 9 6 5 8 3 4 13 20 7 10
Output example:
31
Example explanation:
Goldilocks can set the thermostat temperature to $7 or $8, which will make cows $1 and $4 comfortable, $2 hot and $3 cold.
A total of $31 $units of milk can be obtained.
Problem solving ideas
The meaning of the question is to give an interval on an infinite number axis, and then take any value (temperature) on the interval, and the contribution to the answer (output) is $y $. If the value is taken in the left part of this interval, the contribution to the answer is $x $. If the value is taken in the right part of this interval, the contribution to the answer is $z $.
It is equivalent to adding corresponding values to each interval, which can be associated with difference.
The data range of $N $given in this question is very small, but the value range is very large. In fact, we will not use more than $2N $subscripts, so we can discretize them.
If the original array is obtained from the difference fraction group, it is actually the prefix and sum of the difference fraction group. The position with the value of $0 $can be ignored, because $0 $has no effect on the prefix and. So you can skip all $0 $when calculating the maximum value. This means that when calculating the prefix sum, you only need to use all the numbers that have appeared. Therefore, we only need to save the subscripts of the left and right endpoints of the interval.
Here, you can use map to implement, $key $is the subscript, $value $is $x $or $y $or $z $. And when traversing, the map will realize the orderly sorting of $key $, so you can use the map to realize discretization.
The AC code is as follows:
1 #include <cstdio> 2 #include <map> 3 #include <algorithm> 4 using namespace std; 5 6 const int INF = 2e9; 7 8 map<int, int> mp; 9 10 int main() { 11 int n, x, y, z; 12 scanf("%d %d %d %d", &n, &x, &y, &z); 13 for (int i = 0; i < n; i++) { 14 int left, right; 15 scanf("%d %d", &left, &right); 16 17 mp[-INF] += x, mp[left] -= x; 18 mp[left] += y, mp[right + 1] -= y; 19 mp[right + 1] += z, mp[INF] -= z; 20 } 21 22 int sum = 0, ret = 0; 23 for (auto &it : mp) { 24 sum += it.second; 25 ret = max(ret, sum); 26 } 27 printf("%d", ret); 28 29 return 0; 30 }
If implemented with map, the constant will be relatively large, and the operation efficiency is not as high as that of handwriting. Therefore, the way to realize discretization by handwriting is given below.
- First, store the left and right subscripts used each time in the array $l $and $r $respectively.
- At the same time, all subscripts are stored in $all $. Then sort and remove the duplicate. At this time, all subscripts used will be mapped to $0, 1,... $, in order of size, Achieve the effect of order preservation.
- Then traverse the arrays $l $and $r $, find the mapped subscript through bisection, and operate at the left and right interval endpoints corresponding to the difference array $b $.
- Finally, find the prefix sum of the difference fraction group, and the maximum value is the answer.
The AC code is as follows:
1 #include <cstdio> 2 #include <vector> 3 #include <algorithm> 4 using namespace std; 5 6 const int N = 2e4 + 10, INF = 2e9; 7 8 vector<int> alls; 9 int l[N], r[N], b[2 * N]; 10 11 int find(int x) { 12 int left = 0, right = alls.size() - 1; 13 while (left < right) { 14 int mid = left + right >> 1; 15 if (alls[mid] >= x) right = mid; 16 else left = mid + 1; 17 } 18 19 return left; 20 } 21 22 int main() { 23 int n, x, y, z; 24 scanf("%d %d %d %d", &n, &x, &y, &z); 25 for (int i = 0; i < n; i++) { 26 scanf("%d %d", l + i, r + i); 27 alls.push_back(l[i]), alls.push_back(r[i] + 1); 28 } 29 alls.push_back(-INF), alls.push_back(INF); 30 31 sort(alls.begin(), alls.end()); 32 alls.erase(unique(alls.begin(), alls.end()), alls.end()); 33 34 for (int i = 0; i < n; i++) { 35 int left = find(l[i]), right = find(r[i] + 1); 36 b[0] += x, b[left] -= x; 37 b[left] += y, b[right] -= y; 38 b[right] += z, b[alls.size() - 1] -= z; 39 } 40 41 int sum = 0, ret = 0; 42 for (int i = 0; i < alls.size() - 1; i++) { 43 sum += b[i]; 44 ret = max(ret, sum); 45 } 46 printf("%d", ret); 47 48 return 0; 49 }
reference material
AcWing 1952. Goldilocks and N cows (winter vacation daily question 2022): https://www.acwing.com/video/3667/