ARC092E Both Sides Merger

Posted flyfeather6

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ARC092E Both Sides Merger相关的知识,希望对你有一定的参考价值。

题意

给你一个长度为 (n) 的序列 (a)

有两种操作:

  1. 选择一个端点的数,删除

  2. 选择一个非端点的数,将其变为相邻左右两数之和,删去左右两边的数。

若干次操作后序列只剩下一个数,求最大值,并输出方案。

(2 leq n leq 1000,|a_i| leq 10^9)

传送门

思路

首先对于二操作,其实一个数所属位置的奇偶性不会改变,奇数位加到奇数位,偶数位加到偶数位,所以最终的最大值中,会由偶数位正数相加和奇数位正数相加产生。

为什么是正数呢?因为对于负数,中间的我们只需要对它进行二操作,将三个数并成一个,直到两边都是正数为止,负数就消失了。两边的就一直删到需要相应位的正数为止即可。然后我们就得到了一个一个要一个不要的数列,只需要对第二个位置一直做操作二即可。

注意特判全部都是负数的情况。

#include <bits/stdc++.h>
using std::max; 
const int N=1005;
long long sum1,sum2;
int a[N],ans[N],n,cnt,now,l,r,t;
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		if (i&1) sum1+=max(a[i],0);
		else sum2+=max(a[i],0);
	}
	if (sum1==0 && sum2==0){
		int mx=1;
		for (int i=1;i<=n;i++) if (a[i]>a[mx]) mx=i;
		printf("%d
%d
",a[mx],n-1);
		for (int i=n;i>mx;i--) printf("%d
",i);
		for (int i=1;i<mx;i++) printf("%d
",1);
		return 0; 
	}
	if (sum1>sum2){
		t=1;
		printf("%lld
",sum1);	
	} else t=0,printf("%lld
",sum2);
	int i=n;
	for (;(i%2)!=t || a[i]<0;i--) ans[++cnt]=i;
	r=i;
	i=1;
	for (;(i%2)!=t || a[i]<0;i++) ans[++cnt]=1;
	l=i;
	for (i=l;i<=r;i+=2) 
		if (a[i]<0 && (i%2)==t) ans[++cnt]=now*2+1;
		else now++;
	for (int i=1;i<now;i++) ans[++cnt]=2;
	printf("%d
",cnt);
	for (int i=1;i<=cnt;i++) printf("%d
",ans[i]); 
}

以上是关于ARC092E Both Sides Merger的主要内容,如果未能解决你的问题,请参考以下文章

Equal Sides Of An Array

6kyu Equal Sides Of An Array

sql IPL Sides拥有2008年至2016年的大多数队长

storm trident merger

Manifest merger failed

SQL Server 2008的实用小道具——merger