【问题标题】:Maximise the sum of one array while keeping the sum of corresponding elements of other array less than k最大化一个数组的总和,同时保持另一个数组对应元素的总和小于k
【发布时间】:2015-07-04 06:51:25
【问题描述】:

我有两个数组,我必须从第一个数组中选择一些元素,以便它们的总和最大化,而第二个数组的相应元素的总和小于 k。

到目前为止我能想到一个递归解决方案,我需要一个迭代解决方案。

例子:

数组 1 : 2 2 5 4 3 6 10

数组 2:4 3 2 5 4 10 7 和 k = 15

所有数字都是正数。

【问题讨论】:

  • 在你的情况下,答案是什么?
  • 我会从第一个数组中选择10、4和5,这样第二个数组中对应元素的总和就是14。
  • 这不是背包问题吗?
  • @user1990169 完全同意:)

标签: arrays algorithm language-agnostic


【解决方案1】:

假设每个数组有 n 个元素。一种解决方案是尝试所有可能的 n 个元素组合,这意味着时间复杂度为O(2^n)

而使用动态规划可以达到O(n*k)的时间复杂度:

dp[i][j] = x的意思是对于前i个元素,从数组2中选择一些元素,数组2的被选择元素的和为j(0 dp[n][j] (0

状态转移方程是尝试是否选择数组2的第i个元素。如未选中,dp[i][j] = dp[i-1][j];如果选中,dp[i][j] 可以是max(dp[i-1][j], dp[i-1][j-b[i]] + a[i]),这里是b[i]

    for(int i=1;i<=n;i++) {
        for(int j=0;j<k;j++) {
            dp[i][j] = 0;
        }
    }
    if(b[1] < k) {
        dp[1][b[0]] = a[0];
    }
    for(i=2;i<=n;i++) {
        for(j=0;j<k;j++) {
            dp[i][j] = dp[i-1][j];
            if(j >= b[i] && dp[i-1][j - b[i]] + a[i] > dp[i][j]) {
                dp[i][j] = dp[i-1][j - b[i]] + a[i];
            }
        }
    }

答案是max(d[[n][j]), 0 &lt;= j&lt; k

请根据nk的大小选择不同的算法。

【讨论】:

    【解决方案2】:

    数组的每个元素都可以存在或缺失,从而导致2^N 组合被评估。例如,您可以生成从 02^N-1 的数字,并使用它们的各个位作为此类存在/不存在的指示符。

    整个解决方案可以通过这个Python one-liner(这里分为三行)找到:

    import itertools
    
    a1 = [2, 2, 5, 4, 3, 6, 10]
    a2 = [4, 3, 2, 5, 4, 10, 7]
    k = 15
    
    print sorted((sum(itertools.compress(a1, s)), s)
        for s in itertools.product([0, 1], repeat=len(a1))
            if sum(itertools.compress(a2, s)) < k)[-1][1]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      • 1970-01-01
      • 2022-10-21
      • 2013-01-12
      • 1970-01-01
      • 2020-11-11
      • 2021-05-15
      相关资源
      最近更新 更多