我无法解决如何选择元素的问题。
例如,如果我们有1,2,3,4,5,6,7,8,9,10
我们选择4,5
然后我们不能选择6,7,8,但我们可以选择第9个所以,我猜一般
如果我们选择2个连续元素 arr [i]和arr [i + 1] ,
然后我们不能从接下来的3个值 arr [i + 2],arr [i + 3],arr [i + 4] 中选择,我们可能只会选择来自 arr [i + 5]
代表:
使用 9个元素
来考虑此数组输入:arr [] = {100,200,100,500,900,500,300,400,100}
输出:1500
此最大总和应为:1500
通过取第4,5和9位的值获得
即500 + 900 + 100 = 1500
另一个例子:
考虑使用 10个元素
的此数组输入:arr [] = {500,700,300,500,900,700,600,400,700,500}
输出:2800
选择(2,5,9,10)
的元素即700 + 900 + 700 + 500 = 2800
答案 0 :(得分: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;
}