对值的最大总和,使得同一组对的值应该是范围 [1, N] 内 i 的倍数
给定一个大小为N的配对数组arr[] ,其中配对的第一个元素是配对的值,第二个元素是配对所属的组,任务是找到配对值的最大和,这样对于范围[1, N]中的所有i ,同一组的对数应该是i的倍数。
例子:
Input: arr[] = {{5, 3}, {9, 3}, {6, 3}, {7, 3}, {9, 3}, {7, 3}}, N = 6
Output : {43, 43, 43, 32, 38, 43}
Explanation:
There are 6 pairs of groups 3.
For i = 1, select all the pairs of group 3, since 6 % 1 = 0, then the sum will be 5 + 9 + 6 + 7 + 9 + 7 = 43.
For i = 2, select all the pairs of group 3 since 6 % 2 = 0, then the sum will be 5 + 9 + 6 + 7 + 9 + 7 = 43.
For i = 3, select all the pairs of group 3 since 6 % 3 = 0, then the sum will be 5 + 9 + 6 + 7 + 9 + 7 = 43.
For i = 4, select 4 pairs of group 3 whose sum of value is largest, then the sum will be 9 + 9 + 7 + 7 = 32.
For i = 5, select 5 pairs of group 3 whose sum of value is largest, then the sum will be 9 + 9 + 7 + 7 + 6 = 38.
For i = 6, select all the pairs of group 3 since 6 % 6 = 0, then the sum will be 5 + 9 + 6 + 7 + 9 + 7 = 43.
Input: arr[] = {{6, 1}, {8, 2}, {3, 1}, {1, 2}, {5, 1}, {1, 2}, {5, 1}}, N = 7
Output : {29, 28, 26, 19, 0, 0, 0}
方法:解决问题的最简单的想法是在组的基础上分离数组的元素,然后使用前缀和数组在O(1)中找到每个组的元素之和。请按照以下步骤解决问题:
- 初始化哈希映射m ,第一个元素为整数,第二个元素为向量。
- 使用变量i在[1, N]范围内迭代,并将向量的所有对插入它们各自的组中。
- 将哈希图中的所有向量按升序排序,并将它们存储在一个向量中,比如v 。
- 初始化向量说,大小为N的ans并将其存储在[1, N]范围内的所有i的答案和 分别为每个组的前缀和数组。
- 使用变量i在[0, v.size()-1]范围内迭代并执行以下步骤:
- 使用变量j初始化一个向量c并在[0, v[i].size()-1]范围内迭代并执行以下步骤:
- 如果j等于0 ,则将v[i][j]附加到向量c,否则附加c.back() + v[i][j]。
- 将向量c插入向量it中。
- 使用变量j初始化一个向量c并在[0, v[i].size()-1]范围内迭代并执行以下步骤:
- 现在,使用变量i遍历向量it并执行以下步骤:
- 使用变量j在[1, it[i].size()]范围内迭代并执行以下步骤:
- 如果从向量it[i]中选择了j个元素,则将不能取的元素的数量存储在变量left中。
- 在ans[j-1]中添加it[i].back() – it[i][left-1] (减去左边的最小数字)。
- 使用变量j在[1, it[i].size()]范围内迭代并执行以下步骤:
- 执行上述步骤后,打印向量ans 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum sum of
// pair values, such that the number of
// pairs of the same group should be a
// multiple of i for all i in the
// range [1, N]
void findMaximumSumValue(vector > arr, int n)
{
// Map for storing elements of same group
// together
map > mp;
// Segregate students on the basis of group
for (int i = 0; i < n; i++) {
mp[arr[i].second - 1].push_back(arr[i].first);
}
vector > v;
// Pushing all the vectors in the map to v
for (auto i : mp) {
v.push_back(i.second);
// Sort all the groups in ascending order
sort(v.back().begin(), v.back().end());
}
// Vector to store answer
vector ans(n, 0);
// Vector to store prefix sum array
// for each group
vector > it;
// Traverse through the groups
for (auto i : v) {
vector c;
// Save prefix sum array in vector C
for (int j = 0; j < (int)i.size(); j++) {
if (j == 0) {
c.push_back(i[j]);
}
else {
c.push_back(c.back() + i[j]);
}
}
// Insert the prefix sum c in it
it.push_back(c);
}
// Traverse through the prefix function of each group
for (auto i : it) {
// Traverse for all number of elements in i
for (int j = 1; j <= (int)i.size(); j++) {
// Check the number students to be left.
int left = (int)i.size() % j;
int del = 0;
// If left is greater than 0 subtract the
// value of left smallest elements
if (left > 0)
del = i[left - 1];
ans[j - 1] += (i.back() - del);
}
}
// Print the answer list for every
// possible size
for (int i = 0; i < n; i++) {
cout << ans[i] << " ";
}
cout << endl;
}
// Driver Code
int main()
{
// Given Input
vector > arr
= { { 5, 3 }, { 9, 3 }, { 6, 3 },
{ 7, 3 }, { 9, 3 }, { 7, 3 } };
int N = arr.size();
// Function Call
findMaximumSumValue(arr, N);
return 0;
}
Python3
# Python 3 program for the above approach
# Function to find the maximum sum of
# pair values, such that the number of
# pairs of the same group should be a
# multiple of i for all i in the
# range [1, N]
def findMaximumSumValue(arr, n):
# Map for storing elements of same group
# together
mp = {}
# Segregate students on the basis of group
for i in range(n):
if (arr[i][1]-1) not in mp:
mp[arr[i][1] - 1] = []
mp[arr[i][1] - 1].append(arr[i][0])
v = []
# Pushing all the vectors in the map to v
for i in mp:
v.append(mp[i])
# Sort all the groups in ascending order
v[0].sort()
# Vector to store answer
ans = [0]*(n)
# Vector to store prefix sum array
# for each group
it = []
# Traverse through the groups
for i in v:
c = []
# Save prefix sum array in vector C
for j in range(len(i)):
if (j == 0):
c.append(i[j])
else:
c.append(c[-1] + i[j])
# Insert the prefix sum c in it
it.append(c)
# Traverse through the prefix function of each group
for i in it:
# Traverse for all number of elements in i
for j in range(1, len(i) + 1):
# Check the number students to be left.
left = len(i) % j
dele = 0
# If left is greater than 0 subtract the
# value of left smallest elements
if (left > 0):
dele = i[left - 1]
ans[j - 1] += (i[-1] - dele)
# Print the answer list for every
# possible size
for i in range(n):
print(ans[i], end=" ")
print()
# Driver Code
if __name__ == "__main__":
# Given Input
arr = [[5, 3], [9, 3], [6, 3],
[7, 3], [9, 3], [7, 3]]
N = len(arr)
# Function Call
findMaximumSumValue(arr, N)
# This code is contributed by ukasp.
43 43 43 32 38 43
时间复杂度: O(N 2 )
辅助空间: O(N)