codeforces D. Omkar and Circle

在这里插入图片描述

题目

题意:

对于每一个序列中的元素,你可以将这个元素的相邻项相加,然后代替这个元素,以此类推,直到剩下最后一个元素,问最后一个数字最大是多少。

思路:

我们可以发现,如果要将这些数字归成一个的情况下,需要经过 n − 1 2 \frac{n-1}{2} 2n1次,我们可以发现,当两个最小的数字相邻的时候,我们无法将这两个都作为中间数被替换,所以也就是说,我们需要求出不相邻的数字的总和的最大,所以我们每次都是相加 n − 1 2 + 1 \frac{n-1}{2}+1 2n1+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=ai2+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) aiain1(in+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
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值