Algorithm 确定具有给定最大值的关键帧子阵列的最大和

Algorithm 确定具有给定最大值的关键帧子阵列的最大和,algorithm,Algorithm,我有如下二维数组:成对 3,3 4,3 3,2 2,2 2,1 现在我想找出具有最大键和且其值和=6的子数组 使用sumof值为6的不同子阵列 [[3,3],[4,3]] ,Sum = 7 [[3,3],[3,2],[2,1]] ,Sum = 8 [[3,3],[2,2],[2,1]] ,Sum = 7 [[4,3],[3,2],[2,1]],sum = 9 [[4,3],[2,2],[2,1]],sum =8 对于上述阵列元素[4,3][3,2],[2,1]形成子阵列,其值之和为6,

我有如下二维数组:成对

3,3 
4,3
3,2 
2,2
2,1 
现在我想找出具有最大键和且其值和=6的子数组

使用sumof值为6的不同子阵列

[[3,3],[4,3]] ,Sum = 7
[[3,3],[3,2],[2,1]] ,Sum = 8
[[3,3],[2,2],[2,1]] ,Sum = 7
[[4,3],[3,2],[2,1]],sum = 9
[[4,3],[2,2],[2,1]],sum =8
对于上述阵列元素[4,3][3,2],[2,1]形成子阵列,其值之和为6,即3+2+1=6 上述子阵列的关键帧之和=9,这是最大值


我无法正确思考它是否可以通过DP或基本迭代来解决。任何指针/提示都会有所帮助。

这可以使用动态规划来解决,我们可以迭代每个索引,可以将当前索引添加到答案中,也可以选择忽略它,然后我们可以通过记忆来降低问题的复杂性

编写了C++中的递归动态编程解决方案:

#include <iostream>
#define INF 100000000
using namespace std;

int arr[100][2], sumOfValues, n, dp[100][10000];

int solve(int index, int currentSum){
    if(index == n){
        if(currentSum == sumOfValues) return 0;
        else return -INF;
    }
    if(dp[index][currentSum] != -1) return dp[index][currentSum];
    int v1 = solve(index+1, currentSum + arr[index][1]) + arr[index][0];    //take current element
    int v2 = solve(index+1, currentSum);    //do not take current element
    return dp[index][currentSum] = max(v1, v2);
}

int main() {
    n = 5;
    sumOfValues = 6;
    arr[0][0] = 3;arr[0][1] = 3;
    arr[1][0] = 4;arr[1][1] = 3;
    arr[2][0] = 3;arr[2][1] = 2;
    arr[3][0] = 2;arr[3][1] = 2;
    arr[4][0] = 2;arr[4][1] = 1;
    for(int i = 0;i < 100;i++) for(int j = 0;j < 10000;j++) dp[i][j] = -1;
    cout << solve(0, 0) << endl;
    return 0;
}
#包括
#定义INF 100000000
使用名称空间std;
int-arr[100][2],总和值,n,dp[100][10000];
int solve(int索引,int currentSum){
如果(索引==n){
if(currentSum==sumOfValues)返回0;
else返回-INF;
}
如果(dp[index][currentSum]!=-1)返回dp[index][currentSum];
int v1=solve(index+1,currentSum+arr[index][1])+arr[index][0];//取当前元素
int v2=solve(index+1,currentSum);//不接受当前元素
返回dp[index][currentSum]=max(v1,v2);
}
int main(){
n=5;
总和值=6;
arr[0][0]=3;arr[0][1]=3;
arr[1][0]=4;arr[1][1]=3;
arr[2][0]=3;arr[2][1]=2;
arr[3][0]=2;arr[3][1]=2;
arr[4][0]=2;arr[4][1]=1;
对于(inti=0;i<100;i++)对于(intj=0;j<10000;j++)dp[i][j]=-1;

请解释一下你的求和函数,也就是说,
3+3+4+3=7
?@ChrisPickford OP意味着只添加键。
3+3+2=8
这些不是键/值对,它们是数组对象。我仍然需要理解你的算法,但你如何发现这是一个DP问题,以及你是如何想出解决方案的呢?这个问题是数组对象的一个变体吗f common DP problem?@tim tom这是具有精确权重和的
背包问题
。这是一个不同的子集和问题。请注意,它不是一个多项式时间算法,而是一个伪多项式时间算法,我的意思是它的复杂性取决于输入,也就是说,它取决于sumOfValues约束。