Algorithm 具有约束的数组中的最大和
我有一个问题,在给定一个正数数组的情况下,我必须找到元素的最大和,这样就不会选取两个相邻的元素。最大值必须小于给定的某个K。我试着在没有K的情况下思考类似问题,但到目前为止我失败了。对于后一个问题,我有下面的dp ish solnAlgorithm 具有约束的数组中的最大和,algorithm,Algorithm,我有一个问题,在给定一个正数数组的情况下,我必须找到元素的最大和,这样就不会选取两个相邻的元素。最大值必须小于给定的某个K。我试着在没有K的情况下思考类似问题,但到目前为止我失败了。对于后一个问题,我有下面的dp ish soln int sum1,sum2 = 0; int sum = sum1 = a[0]; for(int i=1; i<n; i++) { sum = max(sum2 + a[i], sum1); s
int sum1,sum2 = 0;
int sum = sum1 = a[0];
for(int i=1; i<n; i++)
{
sum = max(sum2 + a[i], sum1);
sum2 = sum1;
sum1 = sum;
}
intsum1,sum2=0;
int sum=sum1=a[0];
对于(int i=1;i
制作原始阵列(A1)的副本(A2)
查找数组中的最大值(A2)
将它的前一个邻居之前的所有值和下一个邻居之后的值提取到一个新数组中(A3)
在新数组中查找最大值(A3)
检查sum是否大于k。如果sum通过检查,则完成检查
如果没有,则需要返回复制的数组(A2),删除第二个大数值(在步骤3中找到),然后从步骤3开始
一旦没有可用于最大数字的数字组合(即,在步骤1中找到的数字+数组中的任何其他数字大于k),则将其从原始数组(A1)中移除,然后从步骤0开始
如果由于某种原因没有有效的组合(例如,数组只有三个数字,或者没有任何数字组合低于k),则抛出异常,或者如果更合适,则返回null
我脑子里能想到的最好的方法就是O(n*K)dp:
int和[n][K+1]={{0};
int i,j;
对于(j=a[0];j a[0]){
对于(j=a[0];j对于(j=a[1];j第一个想法:蛮力
迭代所有合法的索引组合,并动态生成总和
当你超过K时,停止一个序列
保留序列,直到找到一个更大的,比K更小的
第二个想法:也许你可以把它变成一个分而治之的东西…这里有一个没有“k”约束的问题解决方案,这是你开始做的第一步:
在我看来,通过简单地修改下面for循环中的if条件以包含约束,可以很容易地将上述解决方案扩展为具有k约束:possibleMax
// Subproblem solutions, DP
for (int i = start; i <= end; i++) {
int possibleMaxSub1 = maxSum(a, i + 2, end);
int possibleMaxSub2 = maxSum(a, start, i - 2);
int possibleMax = possibleMaxSub1 + possibleMaxSub2 + a[i];
/*
if (possibleMax > maxSum) {
maxSum = possibleMax;
}
*/
if (possibleMax > maxSum && possibleMax < k) {
maxSum = possibleMax;
}
}
//子问题解决方案,DP
for(int i=开始;i最大和){
最大和=可能最大值;
}
*/
if(possibleMax>maxSum&&possibleMax
如原始链接所示,这种方法可以通过增加记忆来改进,这样重复子问题的解决方案就不会被重新计算。或者可以通过使用自底向上的动态规划方法来改进(当前的方法是递归自上而下的方法)
您可以在此处参考自下而上的方法:两个元素的最大和,这样就不会拾取两个相邻元素?2个或更多?在不拾取相邻元素的情况下,在数组中的所有元素上获得最大和…您在步骤5中没有完成,您必须尽可能接近K。示例2 6 2 K=5您的解决方案将是0正确的解决方案is4i不遵循您的逻辑。如果我检查数组中两个最大数字的总和是否小于K,并且我已确保它们彼此不相邻,那么我就完成了。在2 6 2和K=5的情况下,它将是这样的:6是最高的,但新数组中没有值(新数组中不包括相邻的数字)因此,我们在步骤7结束。最大的数字是2(步骤2)。(步骤3)在新数组(A3)中,只有一个2(步骤4)。(步骤5)2+2小于5,所以返回和。@Jenschauder我假设问题是关于找到两个最大的非相邻数的两个和。非常感谢。我是DP新手,这真的很有帮助!!+1:如果我错了,请纠正我-但我相信子集和问题有一个简化:给定子集和的一个实例,“pad”元素:在每两个相邻元素之间-添加一个值k+1
。因此,不太可能找到多项式解,而建议的伪多项式解可能是最优的。[当然,除非k<2^n
,然后只需检查所有组合…]
// Subproblem solutions, DP
for (int i = start; i <= end; i++) {
int possibleMaxSub1 = maxSum(a, i + 2, end);
int possibleMaxSub2 = maxSum(a, start, i - 2);
int possibleMax = possibleMaxSub1 + possibleMaxSub2 + a[i];
/*
if (possibleMax > maxSum) {
maxSum = possibleMax;
}
*/
if (possibleMax > maxSum && possibleMax < k) {
maxSum = possibleMax;
}
}