【问题标题】:Maximum possible sum less than or equal to k in a 2D array using each row使用每一行的二维数组中小于或等于 k ​​的最大可能总和
【发布时间】:2015-10-12 12:38:28
【问题描述】:

给定:一个二维数组,值 K 和 M

问题:使用恰好 M 个元素,使用所有行(即每行应该有一个元素)找到小于或等于 K 的最大可能总和。

这是一个程序的 sn-p,我无法实现每行和 M 的条件。

for (int i = 0 ; i<n ; i++)
    for (int s=0; s<M; s++)
        for (int j=K;j>=0;j--)
            if (dp[s][j] && A[i] + j < K)
                dp[s + 1][j + A[i]] = true;

编辑 1:Rows = M ,即必须从每一行中选择一个元素。

编辑 2:动态编程解决方案,感谢 @6502

ill ret(V(ill) col[101],ill prec[][101],ill s,ill row,ill m,ill k)
{
    if(prec[s][row])
    return prec[s][row];
    else
    {
        if(row==m+1)
        return s;
        ill best=-1;
        int j=row;

        for(int i=0;i<col[j].size();i++)
        {
            if(s+col[j][i] <= k)
            {
                ill x = ret (col,prec,s+col[j][i],row+1,m,k);
                if ((best==-1)||(x>best))
                best=x;

            }
        }
        prec[s][row]=best;
        return best;
    }


}

【问题讨论】:

  • 矩阵有多少行?如果它的行数少于 M 怎么办?我们能满足条件吗?
  • @svs 行总是等于 M ,即。 e 必须从每一行中选择一个元素
  • 有什么限制吗? K 和 M 有多大?
  • @PhamTrung 1 ≤ M ≤ 100 1 ≤ K ≤ 10000

标签: c++ algorithm dynamic-programming


【解决方案1】:

问题可以通过选择(s, row)作为状态来使用动态编程来解决,其中s是当前总和,row是我们需要包含的下一行。

最大原则是有效的,因为无论我们在前几行中做出哪些选择,结果仅取决于当前总和和当前行索引。

在代码中(Python)

cache = {}

data = [[2, 3, 4],
        [2, 3, 4],
        [2, 3, 4]]

M = 3
K = 10

def msum(s, row):
    try:
        return cache[s, row]
    except KeyError:
        if row == M:
            return s
        best = None
        for v in data[row]:
            if s+v <= K:
                x = msum(s+v, row+1)
                if best is None or x > best:
                    best = x
        cache[s, row] = best
        return best

print msum(0, 0)

如果不存在解,则函数返回None(即,即使从每一行中取最小值,我们最终也会超过K)。

【讨论】:

  • 对于二维数组值 = { {2,3,4},{2,3,4},{2,3,4} } , K=10,M=3 ,答案应该是 10(2+4+4) 而你的解决方案是 8。
  • 感谢您的提醒,我最终使用 dfs 方法解决了解决方案,请查看我的代码并查看它。我已经编辑了线程并添加了代码。
  • @shubhamr:可能您在翻译中犯了一些错误,因为答案中的算法正确解决了该测试用例(请参阅编辑,我只是​​添加了输入数据和调用)。跨度>
  • 知道了,非常感谢。
【解决方案2】:

蛮力方法:

bool increase(const std::vector<std::vector<int>>& v, std::vector<std::size_t>& it)
{
    for (std::size_t i = 0, size = it.size(); i != size; ++i) {
        const std::size_t index = size - 1 - i;
        ++it[index];
        if (it[index] > v[index].size()) {
            it[index] = 0;
        } else {
            return true;
        }
    }
    return false;
}

int sum(const std::vector<std::vector<int>>& v, const std::vector<std::size_t>& it)
{
    int res = 0;
    for (std::size_t i = 0; i != it.size(); ++i) {
        res += v[i][it[i]];
    }
    return res;
}

int maximum_sum_less_or_equal_to_K(const std::vector<std::vector<int>>& v, int K)
{
    std::vector<std::size_t> it(v.size());
    int res = K + 1;

    do {
        int current_sum = sum(v, it);
        if (current_sum <= K) {
            if (res == K + 1 || res < current_sum) {
                res = current_sum;
            }
        }
    } while (increase(v, it));
    if (res == K + 1) {
        // Handle no solution
    }
    return res;
}

it 拥有每一行的当前选择。

【讨论】:

    【解决方案3】:

    这可以使用布尔二维表来解决。 dp[r][s] 的值设置为 true,如果可以生成 sum 's' ,则使用恰好 'r' 行(即 [0 到 r-1] 行中的每一行中的一个元素)。使用这个 dp 表,我们可以计算下一个状态为

                  dp[r+1][s] |= dp[r][s-A[r+1][c]]  ; 0 < c < N, 0 < s <= K
    

    其中 N 是列数(基于 0 的索引)。最后返回dp表M-1行设置的max index的值

    以下是自下而上的实现

    // Assuming input matrix is M*N
    int maxSum() {
        memset(dp, false, sizeof(dp));
    
        //Initialise base row
        for (int c = 0; c < N; ++c)
            dp[0][A[0][c]] = true;
    
        for ( int r = 1; r < M; ++r ) {
            for ( int c = 0; c < N; ++c) {
                // For each A[r][c], check for all possible values of sum upto K
                for (int sum = 0; sum <= K; ++sum) {
                    if ( sum-A[r][c] >= 0 && dp[r-1][sum-A[r][c]] )
                        dp[r][sum] = true;
                }
            }
        }
    
        // Return max possible value <= K
        for (int sum = K; sum >= 0; --sum) {
            if ( dp[M-1][sum] )
                return sum;
        }
    
        return 0;
    }
    

    请注意,当前行的 dp 表值仅取决于前一行,因为这种空间优化技巧可用于使用 1-D 表来解决它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-04
      • 2020-11-22
      • 2019-09-26
      • 1970-01-01
      • 1970-01-01
      • 2017-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多