从位置 M 开始,在总共 K 步中最大化值的总和
给定一个包含N对[A, B]的排序数组arr[] ,其中A是X 轴上的位置, B是该位置上的值。所有的位置都是不同的。数组按位置升序排序。
给定两个整数M和K 。任务是最大化从位置M开始可以访问的值的总和,并采取总共K步,其中:
- 通过采取 1 步,可以向右或向左移动1 个位置(从x到x+1或x-1 )。
- 任何位置的值只能与最终总和相加一次。
- 沿Y 轴没有移动。
例子:
Input: arr[][] = {{2, 8}, {6, 3}, {8, 6}}, M = 5, K = 4
Output: 9
Explanation: The optimal way is to:
Move right to position 6 and add 3. Movement 1 position.
Move right to position 8 and add 6. Movement 2 position.
Total movement 3 steps and sum = 3 + 6 = 9.
Input: arr[][] = {{1, 7}, {3, 6}, {4, 5}, {6, 5}}, M = 3, K = 4
Output: 18
Explanation: The optimal way of movement is:
Add value at position 3 to answer.
Move right to position 4 and add 5.
Move left to position 1 and add 7.
Total sum = 6 + 5 + 7 = 18.
Notice that position 3 can be visited twice but value is added only once.
Input: arr[][] = {{0, 3}, {6, 4}, {8, 5}}, M = 3, K = 2
Output: 0
Explanation: Movement can be most K = 2 positions and cannot reach any position with points .
方法:该方法基于前缀和的概念。站在需要确定的任何位置可以覆盖的范围,然后可以从前缀和数组计算总点数。请按照以下步骤操作:
- 找到最大可能位置的前缀和。之后,执行两个循环。
- 第一个循环将是首先向右行驶,然后考虑向左行驶。
- 当先向左移动时会发生第二个循环,然后考虑向右移动。
- 所有可行范围内覆盖的最大种子数为最终答案。
下面是上述方法的实现
C++
// C++ code to implement above approach
#include
using namespace std;
// Function to calculate maximum points
// that can be collected
int maxTotalPoints(vector >& arr,
int M, int K)
{
int MX = 2e5 + 2;
int i, l, r, ans = 0;
// Incremented positions by one
// to make calculations easier.
M++;
vector prefix_sum(MX);
for (auto& it : arr)
prefix_sum[it[0] + 1] = it[1];
for (i = 1; i < MX; i++)
prefix_sum[i] += prefix_sum[i - 1];
for (r = M; r < MX && r <= M + K; r++) {
l = min(M, M - (K - 2 * (r - M)));
l = max(1, l);
ans = max(ans, prefix_sum[r] -
prefix_sum[l - 1]);
}
for (l = M; l > 0 && l >= M - K; l--) {
r = max(M, M + (K - 2 * (M - l)));
r = min(MX - 1, r);
ans = max(ans, prefix_sum[r] -
prefix_sum[l - 1]);
}
return ans;
}
// Driver code
int main()
{
vector> arr{{2, 8}, {6, 3}, {8, 6}};
int M = 5;
int K = 4;
cout<
Java
// Java code to implement above approach
import java.util.*;
class GFG
{
// Function to calculate maximum points
// that can be collected
static int maxTotalPoints(int[][] arr,
int M, int K)
{
int MX = (int) (2e5 + 2);
int i, l, r, ans = 0;
// Incremented positions by one
// to make calculations easier.
M++;
int []prefix_sum = new int[MX];
for (int []it : arr)
prefix_sum[it[0] + 1] = it[1];
for (i = 1; i < MX; i++)
prefix_sum[i] += prefix_sum[i - 1];
for (r = M; r < MX && r <= M + K; r++) {
l = Math.min(M, M - (K - 2 * (r - M)));
l = Math.max(1, l);
ans = Math.max(ans, prefix_sum[r] -
prefix_sum[l - 1]);
}
for (l = M; l > 0 && l >= M - K; l--) {
r = Math.max(M, M + (K - 2 * (M - l)));
r = Math.min(MX - 1, r);
ans = Math.max(ans, prefix_sum[r] -
prefix_sum[l - 1]);
}
return ans;
}
// Driver code
public static void main(String[] args)
{
int [][]arr = {{2, 8}, {6, 3}, {8, 6}};
int M = 5;
int K = 4;
System.out.print(maxTotalPoints(arr, M, K));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python code to implement above approach
# Function to calculate maximum points
# that can be collected
def maxTotalPoints(arr, M, K):
MX = (int)(2e5 + 2);
i, l, r, ans = 0, 0, 0, 0;
# Incremented positions by one
# to make calculations easier.
M += 1;
prefix_sum = [0 for i in range(MX)];
for it in arr:
prefix_sum[it[0] + 1] = it[1];
for i in range(MX):
prefix_sum[i] += prefix_sum[i - 1];
for r in range(M, (M + K + 1) and ( r < MX and r <= M + K)):
l = min(M, M - (K - 2 * (r - M)));
l = max(1, l);
ans = max(ans, prefix_sum[r] - prefix_sum[l - 1]);
for l in range(M, (M - K - 1) and l > 0, -1):
r = max(M, M + (K - 2 * (M - l)));
r = min(MX - 1, r);
ans = max(ans, prefix_sum[r] - prefix_sum[l - 1]);
return ans;
# Driver code
if __name__ == '__main__':
arr = [[2, 8], [6, 3], [8, 6]];
M = 5;
K = 4;
print(maxTotalPoints(arr, M, K));
# This code is contributed by 29AjayKumar
C#
// C# code to implement above approach
using System;
class GFG
{
// Function to calculate maximum points
// that can be collected
static int maxTotalPoints(int[,] arr,
int M, int K)
{
int MX = (int) (2e5 + 2);
int i, l, r, ans = 0;
// Incremented positions by one
// to make calculations easier.
M++;
int []prefix_sum = new int[MX];
for (int it = 0; it < arr.GetLength(0); it++) {
prefix_sum[arr[it, 0] + 1] = arr[it, 1];
}
for (i = 1; i < MX; i++)
prefix_sum[i] += prefix_sum[i - 1];
for (r = M; r < MX && r <= M + K; r++) {
l = Math.Min(M, M - (K - 2 * (r - M)));
l = Math.Max(1, l);
ans = Math.Max(ans, prefix_sum[r] -
prefix_sum[l - 1]);
}
for (l = M; l > 0 && l >= M - K; l--) {
r = Math.Max(M, M + (K - 2 * (M - l)));
r = Math.Min(MX - 1, r);
ans = Math.Max(ans, prefix_sum[r] -
prefix_sum[l - 1]);
}
return ans;
}
// Driver code
public static void Main()
{
int [,]arr = {{2, 8}, {6, 3}, {8, 6}};
int M = 5;
int K = 4;
Console.Write(maxTotalPoints(arr, M, K));
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
9
时间复杂度: O(X),其中 X 是最大位置
辅助空间: O(X)