Arrays 阵列中的最大和,以便可以选择5个元素中的2个连续atmost

Arrays 阵列中的最大和,以便可以选择5个元素中的2个连续atmost,arrays,algorithm,subsequence,groupwise-maximum,Arrays,Algorithm,Subsequence,Groupwise Maximum,我无法解决如何选择元素的问题 例如,如果我们有1,2,3,4,5,6,7,8,9,10 我们选择4,5 那么我们不能选择6、7、8,但我们可以选择9 所以,我想总的来说 如果我们选择两个连续元素arr[i]和arr[i+1] 然后我们不能从接下来的3个值中选择,我们只能从arr[i+2]、arr[i+3]、arr[i+4]中选择 例如: 考虑这个包含9个元素的数组 输入:arr[]={100200100500900500300400100} 输出:1500 最大金额应为:1500 通过取第4、5

我无法解决如何选择元素的问题

例如,如果我们有1,2,3,4,5,6,7,8,9,10

我们选择4,5

那么我们不能选择6、7、8,但我们可以选择9

所以,我想总的来说

如果我们选择两个连续元素arr[i]和arr[i+1]

然后我们不能从接下来的3个值中选择,我们只能从arr[i+2]、arr[i+3]、arr[i+4]中选择

例如:

考虑这个包含9个元素的数组

输入:arr[]={100200100500900500300400100}

输出:1500

最大金额应为:1500

通过取第4、5和9处的值获得

i、 e 500+900+100=1500

另一个例子:

考虑这个包含10个元素的数组

输入:arr[]={500700300500900700600400700500}

输出:2800

在(2、5、9、10)处选择图元


i、 e 700+900+700+500=2800对我来说,这可以通过对动态规划算法的简单修改来实现。实际上,您可以添加一个变量来指示是否拾取了最后一个元素。假设您正在考虑idx位置的元素,您需要一个变量来告诉您是否拾取了idx-1:(1)如果没有,您还没有拾取任何连续的元素,您可以继续拾取idx+1,(2)如果是,您应该从idx+4开始,因为idx+1、idx+2、idx+3不再允许拾取

下面是C++中的一个实现:

    const int n = 1000;

    int arr[n];


    int dp[n][2];
    bool mark[n][2];

    int rec(int idx, bool idx_minus1_picked){
        if(idx >= n){
            return 0; // we have reached end of array
        }

        if(mark[idx][lidx_minus1_picked]){
            return dp[idx][idx_minus1_picked];
        }

        int &ret = dp[idx][idx_minus1_picked];
        ret = 0;

        if(idx_minus1_picked){
            //get the maximum between picking or not picking arr[idx]
            ret = max(arr[idx] + rec(idx + 4, false), rec(idx + 1, false));
        }
        else{
            ret = max(arr[idx] + rec(idx + 1, true), rec(idx + 1, false));
        }

        return ret;

    }

int main(){
    int answer = rec(0, false);
    return 0;
}

对我来说,这可以通过对动态规划算法的简单修改来实现。实际上,您可以添加一个变量来指示是否拾取了最后一个元素。假设您正在考虑idx位置的元素,您需要一个变量来告诉您是否拾取了idx-1:(1)如果没有,您还没有拾取任何连续的元素,您可以继续拾取idx+1,(2)如果是,您应该从idx+4开始,因为idx+1、idx+2、idx+3不再允许拾取

下面是C++中的一个实现:

    const int n = 1000;

    int arr[n];


    int dp[n][2];
    bool mark[n][2];

    int rec(int idx, bool idx_minus1_picked){
        if(idx >= n){
            return 0; // we have reached end of array
        }

        if(mark[idx][lidx_minus1_picked]){
            return dp[idx][idx_minus1_picked];
        }

        int &ret = dp[idx][idx_minus1_picked];
        ret = 0;

        if(idx_minus1_picked){
            //get the maximum between picking or not picking arr[idx]
            ret = max(arr[idx] + rec(idx + 4, false), rec(idx + 1, false));
        }
        else{
            ret = max(arr[idx] + rec(idx + 1, true), rec(idx + 1, false));
        }

        return ret;

    }

int main(){
    int answer = rec(0, false);
    return 0;
}

为什么不是500+900+500?或者500+900+400?我不太理解这个问题。在第一个示例中,我们不能采用(500+900+500),因为将有3个连续的选择,我们可以有2个连续的选择。是每组5个连续的选择还是每组5个连续的选择?如果我选择非连续的数字,怎么样?我选择索引0,2,4,6,8处的所有数字。。。这有效吗?为什么不是500+900+500?或者500+900+400?我不太理解这个问题。在第一个示例中,我们不能采用(500+900+500),因为将有3个连续的选择,我们可以有2个连续的选择。是每组5个连续的选择还是每组5个连续的选择?如果我选择非连续的数字,怎么样?我选择索引0,2,4,6,8处的所有数字。。。这有效吗?