zoukankan      html  css  js  c++  java
  • CodeForces 1373D. Maximum Sum on Even Positions(最大连续子段和)

    题目:你被给予了一个n个整数的数组a。数组的下标从0开始。你可以逆置一个数组的子数组(连续的)最多一次,你的任务是使得这个数组的偶数位置的数字的和最大。

    分析:奇数长度的子数组翻转并不会改变偶数位置的数字,因此,我们只需要考虑长度为偶数的子区间。偶数长度的子数组我们有两种情况,一种是偶数位置开始,奇数位置结束,另一种是奇数位置开始,偶数位置结束。我们先考虑第一种情况,我们要求出一个子区间翻转的收益,我们存储每个位置的(a[i + 1] - a[i]),i从0开始,每次+2,我们要求出一个连续子段和的最大值,这可以联想到DP-最大连续子段和,对于一个位置的数,如果前缀和 <= 0,那么对于当前的数来说,加上这个前缀不会使得收益变大,因此我们重新令前缀和统计为0。这样两种情况求出后,我们加上这个收益,就是答案。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    using LL = long long;
    const int N = 200005;
    int a[N];
    int main()
    {
    	int t;
    	scanf("%d", &t);
    
    	while (t--)
    	{
    		int n;
    		scanf("%d", &n);
    
    		LL sum = 0;
    
    		for (int i = 0; i < n; ++i)
    		{
    			scanf("%d", &a[i]);
    			if ((i & 1) == 0) sum += a[i];
    		}
    
    		LL mx = 0;
    		LL diff1 = 0;
    		//偶开头
    		for (int i = 0; i + 1 < n; i += 2)
    		{
    			diff1 += a[i + 1] - a[i];
    			diff1 = max(0LL, diff1);
    			mx = max(mx, diff1);
    		}
    
    		LL diff2 = 0;
    
    		for (int i = 1; i + 1 < n; i += 2)
    		{
    			diff2 += a[i] - a[i + 1];
    			diff2 = max(0LL, diff2);
    			mx = max(mx, diff2);
    		}
    
    		printf("%lld
    ", sum + mx);
    	}
    
    
    	return 0;
    }
    
    
  • 相关阅读:
    判断用户分辨率调用不同的CSS样式文件
    译文:创建性感的CSS
    CSS控制文字的显示与隐藏时引出的Bug
    设计规范的理想
    浏览器不兼容的源头
    图片垂直居中的使用技巧
    CSS命名规范
    5.2 微格式
    如何在本地使用 Yahoo! BrowserPlus
    如何让 Firefox 2 和 Firefox 3 版本并存
  • 原文地址:https://www.cnblogs.com/pixel-Teee/p/13229768.html
Copyright © 2011-2022 走看看