Codeforces1372 D. Omkar and Circle

题意:

给定长度为n的序列a,表示有一个环,保证n是奇数
一次操作,你需要选择一个数,将这个数替换为左右与其相邻两个数的和,并删除这两个相邻的数
重复操作直到只剩下一个数,问剩下的数的可能最大值是多少

数据范围:n<=2e5

解法:

发现每次将三个数合并为一个数,减少了两个,那么(n-1)/2次操作之后只剩下一个数,权值(n+1)/2个数的和。
因为删除的是中间的数,发现最后删除的(n-1)/2数是不相邻的,那么留下的数一定存在两个数相邻,
确定这两个相邻的数就能确定其他被删除的数,O(n)枚举一下这两个数即可。

计算不相邻数的和可以对奇偶位置分别计算前缀和来做

code:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=2e5+5;
int sum[maxm][2];
int a[maxm];
int n;
signed main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=1;i<=n;i++){
        sum[i][0]=sum[i-1][0];
        sum[i][1]=sum[i-1][1];
        sum[i][i%2]+=a[i];
    }
    int ans=0;
    //选择a[i]和a[i-1]
    for(int i=2;i<=n;i++){
        int temp=tot;
        if(i%2){//奇数位置
            temp=sum[i-1][0]+sum[n][1]-sum[i][1]+a[i];
        }else{//偶数位置
            temp=sum[i-1][1]+sum[n][0]-sum[i][0]+a[i];
        }
        ans=max(ans,temp);
    }
    //选择a[n]和a[1]
    ans=max(ans,sum[n][1]);
    //
    cout<<ans<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44178736/article/details/107398706
今日推荐