Это жадная проблема. Смысл в том, чтобы заметить, что мы всегда должны следить за максимально возможной суммой на каждой итерации. В вашем случае [4, 2, 1, 3]
первая самая большая сумма - 6
, затем 7
, а затем 10
.
Проблема возникает, когда самая большая сумма появляется несколько раз, например [5, 3, 7, 1]
, затем вам нужно выбрать, что лучше начать с [5, 3]
или [7, 1]
.
#include <bits/stdc++.h>
using namespace std;
int n = 6; //array size
int a[] = {2, 1, 7, 1, 5, 3}; //array
vector<pair<int, int>> v; //positions we will analyse
void analyse(){ //this method gets the positions with biggest sum
int sum = 0;
for(int i = 1; i < n; i++) sum = max(sum, a[i - 1] + a[i]);
for(int i = 1; i < n; i++) if(a[i - 1] + a[i] == sum) v.push_back(make_pair(i - 1, i));
}
int evaluate_penalty(int i, int j){ //given a position, this method finds
int l = i, r = j; //the biggest penalty starting there
int penalty = a[i] + a[j];
int val = penalty;
while(i != 0 || j != n - 1){
if(l > 0 && r < n - 1) {
if(a[l - 1] > a[r + 1]) l--;
else r++;
}
else if(l > 0) l--;
else r++;
val += (l != i ? a[l] : 0) + (r != j ? a[r] : 0);
penalty += val;
i = l; j = r;
}
return penalty;
}
int max_penalty(){ //this method finds the biggest penalty
v.clear(); //within all the possible starting positions.
analyse();
int maxPenalty = 0;
for(int i = 0; i < v.size(); i++){
maxPenalty = max(maxPenalty, evaluate_penalty(v[i].first, v[i].second));
}
return maxPenalty;
}
int main(){
cout<<max_penalty()<<endl;
return 0;
}
Сложность O (n²) , НО в большинстве случаев это будет быть О (п) . Учитывая, что наибольшая сумма между двумя последовательными числами равна s , сложность зависит от того, сколько пар последовательных чисел суммируют s . Если есть только один (как в вашем примере [4, 2, 1, 3]
, он завершит sh за одну итерацию, следовательно, O (n). Если массив имеет что-то вроде [1, 1, 1, 1, 1, ..., 1]
, он займет O (n²).