【问题标题】:Algorithm to find maximum sum of elements in an array such that not more than k elements are adjacent查找数组中元素的最大和的算法,使得相邻的元素不超过 k
【发布时间】:2012-04-20 05:12:02
【问题描述】:

我遇到了这个问题。给定一个仅包含正值的数组,您希望在不超过 k 个选定元素的组相邻的约束下最大化选定元素的总和。例如,如果输入是 1 2 3 1 7 9(n=6 和 k =2)。输出将是 21,它来自于选择元素 _ 2 3 _ 7 9。我的简单 DP 解决方案是这样的

#include<stdio.h>
#include<limits.h>
#include<malloc.h>


long maxsum(int n,int k,long *sums){
    long *maxsums;
    maxsums = malloc(sizeof(long)*n);
    int i;
    long add  = 0;
    for(i=n-1;i>=n-k;i--){
        add += sums[i];
        maxsums[i] = add;
    }

    for(i = n-k-1;i>=0;i--){
        int j;
        long sum =0,max = 0,cur;
        for(j=0;j<=k;j++){
            cur = sum;
            if((i+j+1)<n)
                cur += maxsums[i+j+1];  
            if(cur > max) max = cur;
            sum += sums[i+j];
        }
        maxsums[i] = max;
    }
    return maxsums[0];
}

int main(){
    int cases=0,casedone=0;
    int  n,k;
    long *array;
    long maxsum = 0;
    fscanf(stdin,"%d %d",&n,&k);
    array = malloc(sizeof(long)*n);
    int i =0;
      while(casedone < n){
            fscanf(stdin,"%ld",&array[casedone]);
        casedone++;
      }
    printf("%ld",maxsum(n,k,array));
}

但我不确定这是否是有效的解决方案。是否可以进一步降低复杂度?感谢您的帮助

【问题讨论】:

  • “不能选择超过 k 个相邻元素”令人困惑。你的意思是“不能选择超过 k 个元素,并且它们必须是相邻的”还是你的意思是“可以选择任意数量的元素,只要没有超过 k 个的组是相邻的”?
  • 我更新了问题,从示例中可以清楚地看出他的意思是后者。
  • 这是作业吗?如果是这样,它应该被标记为这样。
  • 讨论了完全相同的问题in this question
  • 通过解决这个问题你得到了什么?

标签: c algorithm dynamic-programming


【解决方案1】:

我认为这会奏效:

findMaxSum(int a[], int in, int last, int k) { // in is current index, last is index of last chosen element
    if ( in == size of a[] ) return 0;
    dontChoseCurrent = findMaxSum(a, in+1, last, k); // If current element is negative, this will give better result
    if (last == in-1 and k > 0) { // last and in are adjacent, to chose this k must be greater than 0
        choseCurrentAdjacent = findMaxSum(a, in+1, in, k-1) + a[in];
    }
    if (last != in-1) { // last and in are not adjacent, you can chose this.
        choseCurrentNotAdjacent = findMaxSum(a, in+1, in, k) + a[in];
    }
    return max of dontChoseCurrent, choseCurrentAdjacent, choseCurrentNotAdjacent
}

【讨论】:

  • 对不起..我无法弄清楚你的算法..无论如何它是递归的..它看起来比我的复杂..
【解决方案2】:

您的代码是正确的(至少想法是正确的),另外,到目前为止,我还没有发现任何错误的测试数据。按照你的想法,我们可以列出DP方程

P(v)=max{sum(C[v]~C[v+i-1])+P(v+i+1),0&lt;=i&lt;=k}

在这个等式中,P(v) 表示 {C[v]~C[n]} 中的最大值(我们让 {C[1]~C[n]} 是整个列表),所以我们只需要来确定 P(1)。

目前我还没有找到更好的解决方案,但是你的代码可以优化,确定P(v)后,你可以保存数据i,所以当你找到P(v-1)时,你可以当 i!=k 时,将 sum(C[v-1]+C[v]~C[v+i-1])+P[v+i+1] 与 P[v+1]+C[v] 进行比较,最差的复杂度是一样的,但最好的复杂度是线性的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    相关资源
    最近更新 更多