给定:二维数组,值K和M
问题:使用所有行(即每行应该有一个元素),使用恰好M个元素找出小于或等于K的最大可能总和。
这是一个程序片段,我无法实现每行和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:行= 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;
}
}
答案 0 :(得分: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
)。
答案 1 :(得分:0)
蛮力方法:
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
包含每行的当前选择。
答案 2 :(得分:0)
这可以使用布尔2D表来解决。 dp [r] [s]的值设置为true,如果它可以使用精确的'r'行(即每个[0到r-1]行中的一个元素)生成sum'''。使用这个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表来解决它