题目
题意:
对于每一个序列中的元素,你可以将这个元素的相邻项相加,然后代替这个元素,以此类推,直到剩下最后一个元素,问最后一个数字最大是多少。
思路:
我们可以发现,如果要将这些数字归成一个的情况下,需要经过 n − 1 2 \frac{n-1}{2} 2n−1次,我们可以发现,当两个最小的数字相邻的时候,我们无法将这两个都作为中间数被替换,所以也就是说,我们需要求出不相邻的数字的总和的最大,所以我们每次都是相加 n − 1 2 + 1 \frac{n-1}{2}+1 2n−1+1个数字,举个例子 1 , 2 , 3 , 4 , 5 , 6 , 7 1,2,3,4,5,6,7 1,2,3,4,5,6,7
- 1 , 2 , 3 , 4 , 5 , 6 , 7 − > 1 + 3 + 5 + 7 = 16 1,2,3,4,5,6,7->1+3+5+7=16 1,2,3,4,5,6,7−>1+3+5+7=16
- 2 , 3 , 4 , 5 , 6 , 7 , 1 − > 2 + 4 + 6 + 1 = 13 2,3,4,5,6,7,1->2+4+6+1=13 2,3,4,5,6,7,1−>2+4+6+1=13
- 3 , 4 , 5 , 6 , 7 , 1 , 2 − > 3 + 5 + 7 + 2 = 17 3,4,5,6,7,1,2->3+5+7+2=17 3,4,5,6,7,1,2−>3+5+7+2=17
- 4 , 5 , 6 , 7 , 1 , 2 , 3 − > 4 + 6 + 1 + 3 = 14 4,5,6,7,1,2,3->4+6+1+3=14 4,5,6,7,1,2,3−>4+6+1+3=14
- 5 , 6 , 7 , 1 , 2 , 3 , 4 − > 5 + 7 + 2 + 4 = 18 5,6,7,1,2,3,4->5+7+2+4=18 5,6,7,1,2,3,4−>5+7+2+4=18
- 6 , 7 , 1 , 2 , 3 , 4 , 5 − > 6 + 1 + 3 + 5 = 15 6,7,1,2,3,4,5->6+1+3+5=15 6,7,1,2,3,4,5−>6+1+3+5=15
- 7 , 1 , 2 , 3 , 4 , 5 , 6 − > 7 + 2 + 4 + 6 = 19 7,1,2,3,4,5,6->7+2+4+6=19 7,1,2,3,4,5,6−>7+2+4+6=19
我们可以发现,我们将所有的情况都列出来了,但是如果用暴力的话,那么肯定就会超时了,所以我们可以用前缀和来解决,我们可以每隔一个相加一次即 a i = a i − 2 + a i a_i=a_{i-2}+a_i ai=ai−2+ai,因为这是一个循环,所以我们可以将数组扩大 a n + i = a i a_{n+i}=a_i an+i=ai,这样的话,我们想要知道不同的开头对应的最后的数值就是 a i − a i − n − 1 ( i ≥ n + 1 ) a_{i}-a_{i-n-1}(i\geq n+1) ai−ai−n−1(i≥n+1)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <deque>
#include <stack>
#include <cctype>
using namespace std;
typedef long long ll;
typedef vector<int> veci;
typedef vector<ll> vecl;
typedef pair<int, int> pii;
template <class T>
inline void read(T &ret) {
char c;
int sgn;
if (c = getchar(), c == EOF) return ;
while (c != '-' && (c < '0' || c > '9')) c = getchar();
sgn = (c == '-') ? -1:1;
ret = (c == '-') ? 0:(c - '0');
while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return ;
}
int xxxxxxxxx = 1;
inline void outi(int x) {if (x > 9) outi(x / 10);putchar(x % 10 + '0');}
inline void outl(ll x) {if (x > 9) outl(x / 10);putchar(x % 10 + '0');}
inline void debug(ll x) {cout << xxxxxxxxx++ << " " << x << endl;}
inline void debugs(string s) {cout << s << endl;}
const int maxn = 2e5 + 10;
ll a[maxn << 1];
int main() {
ll ans = 0;
int n; read(n); for (int i = 1; i <= n; i++) read(a[i]), a[n + i] = a[i];
for (int i = 3; i <= n * 2; i++) a[i] += a[i - 2];
for (int i = n + 1; i <= 2 * n; i++) ans = max(ans, a[i] - a[i - n - 1]);
printf("%d", ans);
return 0;
}
/*
7
1 2 3 4 5 6 7
*/