📌  相关文章
📜  对值的最大总和,使得同一组对的值应该是范围 [1, N] 内 i 的倍数

📅  最后修改于: 2022-05-13 01:56:10.334000             🧑  作者: Mango

对值的最大总和,使得同一组对的值应该是范围 [1, N] 内 i 的倍数

给定一个大小为N的配对数组arr[] ,其中配对的第一个元素是配对的值,第二个元素是配对所属的组,任务是找到配对值的最大和,这样对于范围[1, N]中的所有i ,同一组的对数应该是i的倍数。

例子:

方法:解决问题的最简单的想法是在组的基础上分离数组的元素,然后使用前缀和数组在O(1)中找到每个组的元素之和。请按照以下步骤解决问题:

  • 初始化哈希映射m ,第一个元素为整数,第二个元素为向量。
  • 使用变量i[1, N]范围内迭代,并将向量的所有对插入它们各自的组中。
  • 将哈希图中的所有向量按升序排序,并将它们存储在一个向量中,比如v
  • 初始化向量说,大小为Nans并将存储在[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中。
  • 现在,使用变量i遍历向量it并执行以下步骤:
    • 使用变量j[1, it[i].size()]范围内迭代并执行以下步骤:
      • 如果从向量it[i]中选择了j个元素,则将不能取的元素的数量存储在变量left中。
      • ans[j-1]中添加it[i].back() – it[i][left-1] (减去左边的最小数字)。
  • 执行上述步骤后,打印向量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)