zoukankan      html  css  js  c++  java
  • [ABC162F] Select Half 题解

    博客里阅读

    题目大意:给定一个长度为(n)的数列,让你从中取出(lfloorfrac{n}{2} floor)个互不相邻的数,输出这(lfloorfrac{n}{2} floor)个数的和的最大值

    一开始以为就是分类讨论,但最后一个样例怎么都过不去,比赛结束后5min才想到了一个和官方题解的DP不一样的神奇解法...错失涨分的良机

    首先考虑(n)为偶数的情况,手动模拟一下可以发现只有一种情况,取前面一段为奇数位的数和后面一段为偶数位的数

    如(1表示选,0表示不选,接下来讨论的亦如此)

    1 0 1 0 0 1 0 1 0 1
    0 1 0 1 0 1 0 1
    

    然后就是(n)为奇数的情况,这里有一个神奇的性质,我们先来写出几种情况

    1 0 1 0 0 0 1
    1 0 1 0 1 0 0 1 0 1 0
    1 0 1 0 0 1 0 1 0 0 1 0 1
    

    情况多而杂,不好分类讨论,于是我们考虑有没有一种通式能够概括所有的情况,先考虑把奇数位的数全都取上,总共是(lfloorfrac{n}{2} floor+1)个数,只需要减少一个数就可以满足题目的要求

    然后试着把全取奇数位的数与我在上面列出来的情况对比一下,注意看加粗的部分

    1 0 1 0 1 0 1
    1 0 1 0 0 0 1

    1 0 1 0 1 0 1 0 1 0 1
    1 0 1 0 1 0 0 1 0 1 0

    1 0 1 0 1 0 1 0 1 0 1 0 1
    1 0 1 0 0 1 0 1 0 0 1 0 1

    是不是已经发现了,所有的情况都可以视为将全取奇数位的数进行一个两端为1的区间的01翻转(注意所选的区间不能为空),我们要确定这样的一个区间,使得所取的和最大,这个可以用我们熟悉的最大子段和,时间复杂度(O(n)),如果还感觉没理解的话可以再手玩一下

    代码很简短,感觉没理解的相信你看一下代码就懂了

    #include<bits/stdc++.h>
    #define int long long //记得longlong!!
    using namespace std;
    int n,a[200003],fsum[200003],bsum[200003],ans=-2e18,sum,su; //fsum[i]代表的是与i奇偶性相同的数的前缀和,bsum[i]代表的是与i奇偶性相同的数的后缀和
    signed main()
    {
    	scanf("%lld",&n);
    	for(int i=1; i<=n; i++)
    		scanf("%lld",&a[i]);
    	fsum[1]=a[1],fsum[2]=a[2],bsum[n]=a[n],bsum[n-1]=a[n-1];
    	for(int i=3; i<=n; i++)
    		fsum[i]=fsum[i-2]+a[i];
    	for(int i=n-2; i>=1; i--)
    		bsum[i]=bsum[i+2]+a[i];
    	sum=fsum[n];
    	if(n%2==0)
    	{
    		ans=max(fsum[n-1],fsum[n]);
    		for(int i=1; i<=n; i+=2)
    			ans=max(ans,fsum[i]+bsum[i+3]);
    		cout<<ans;
    		return 0;
    	}
    	for(int i=1; i<=n; i++)
    		if(i%2==0)
    			su+=a[i];
    		else
    			su=max(su-a[i],-a[i]),ans=max(ans,sum+su); //最大子段和
    	cout<<ans;
    	return 0;
    }
    
  • 相关阅读:
    Vue学习四:v-if及v-show指令使用方法
    Vue学习三:v-on:click命令及v-html命令学习
    Vue学习二:v-model指令使用方法
    Vue学习一:{{}}html模板使用方法
    jquery及jquery常用选择器使用
    VBA 高级筛选
    vba 如何去掉返回结果两端的双引号?
    VBA RemoveDuplicates方法去重复项
    VBA 根据Find方法根据特定内容查找单元格
    官方文档:Office VBA 参考
  • 原文地址:https://www.cnblogs.com/dzice/p/12690560.html
Copyright © 2011-2022 走看看