原题链接

简要题意:

你可以无限次的把该数组的一个前缀和后缀 \(\times -1\),问最终的最大序列和。

这题盲目WA了数次才知道本质

这题89个数据吊打std

CF真好啊,发现一个错后面就不测了

下面,就以我艰辛的思维历程来构造本篇博客。

算法一

盲猜:所有数都可以变成正数。

然后绝对值相加。

连样例也没测。

然后,\(\frac{2}{89} pts\). 只过了前两个样例,第三个就死了。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std; inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;} int main(){
int n=read(),s=0; while(n--) {
int t=read();
s+=abs(t);
} printf("%d\n",s);
return 0;
}

算法二

突然发现不符合样例!

仔细想了以下,嗯嗯,似乎只有开始的前一段负数和最后的后一段负数可以改变。

然后若有所思的写下一段代码。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std; const int N=1e5+1; inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;} int n,a[N];
int s=0; int main(){
n=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++)
if(a[i]<0) a[i]=-a[i];
else break; //前一段
for(int i=n;i>=1;i--)
if(a[i]<0) a[i]=-a[i];
else break; //后一段
for(int i=1;i<=n;i++) s+=a[i];
printf("%d\n",s);
return 0;
}

交上去,发现得了 \(\frac{6}{89}\) 分。

发现 \(a_i = 0\) 有点问题。

算法三

\(a_i = 0\)?然后加了几个等号。


#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std; const int N=1e5+1; inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;} int n,a[N];
int s=0; int main(){
n=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++)
if(a[i]<=0) a[i]=-a[i];
else break;
for(int i=n;i>=1;i--)
if(a[i]<=0) a[i]=-a[i];
else break;
for(int i=1;i<=n;i++) s+=a[i];
printf("%d\n",s);
return 0;
}

然后得了 \(\frac{8}{89}\) 分。

我却,我答案是负数,它答案是正数

算法四

真正感到自己 脑抽了 挺坚强的。

其实呢,我们还是要重视它,毕竟是 \(C\) 吗。(其实也不难)

你想,比方说前一段是 \(A\),后一段是 \(C\),重叠是 \(B\),一共是 \(S\).(\(\emptyset = 0\))

(指前缀、后缀、重叠部分、总部分的和)

此时答案为:

\[-(A+B)+C
\]

然而:

\[A+B+C=S
\]

(这是因为,中间一段经过两次之后没变,所以还是加上)

所以答案变形为:

\[-(A+B)+C = -(S-C)+C = 2 \times C - S
\]

显然让 \(C\) 越大越好。

那答案不就摆在面前了?

Dev-c++:那你还调试那么多次

因为,\(C\) 肯定是连续的一段并且你可以随便的取,所以:

\[\texttt{C = 原数列的最大子段和}
\]

哎呀,激动地写了个程序。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std; const int N=1e5+1; inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;} int n,a[N];
int s=0,f[N]; int main(){
n=read();
for(int i=1;i<=n;i++) a[i]=read(),s+=a[i];
int ans=a[1]; f[1]=a[1];
for(int i=2;i<=n;i++) f[i]=max(f[i-1]+a[i],a[i]),ans=max(ans,f[i]);
printf("%d\n",ans*2-s);
return 0;
}

看上去没啥问题,然后得了 \(0pt\).

原因: \(\texttt{ans}\) 的初值应该是:

max(a[1],0)

导致第一个样例去世,然后全军覆没~

算法五

终于算是拨云见雾了,结果在临近 \(\texttt{AC}\) 的时候因为初值掉坑。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std; const int N=1e5+1; inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;} int n,a[N];
int s=0,f[N]; int main(){
n=read();
for(int i=1;i<=n;i++) a[i]=read(),s+=a[i];
int ans=max(a[1],0); f[1]=a[1];
for(int i=2;i<=n;i++) f[i]=max(f[i-1]+a[i],a[i]),ans=max(ans,f[i]);
printf("%d\n",ans*2-s);
return 0;
}

终于 \(\text{AC}\) 了。时间复杂度:\(O(n)\).

CF33C Wonderful Randomized Sum 题解的更多相关文章

  1. 【极值问题】【CF33C】 Wonderful Randomized Sum

    传送门 Description 给你一个数列\(A\),你可以选择任意一个前缀和任意一个后缀,前缀后缀可重合.给他们乘\(-1\).求最大能获得的序列和. Input 第一行是一个数\(n\)代表数列 ...

  2. Ural 1248 Sequence Sum 题解

    目录 Ural 1248 Sequence Sum 题解 题意 题解 程序 Ural 1248 Sequence Sum 题解 题意 给定\(n\)个用科学计数法表示的实数\((10^{-100}\s ...

  3. LeetCode Continuous Subarray Sum 题解 同余前缀和 Hash表

    文章目录 题意 思路 特殊情况k=0 Source Code 1 Source Code 2 题意 给定一个数组和一个整数k,返回是否存在一个长度至少为2的连续子数组的和为k的倍数. 思路 和上一篇博 ...

  4. Hdoj 1003.Max Sum 题解

    Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum ...

  5. [LeetCode]Combination Sum题解(DFS)

    Combination Sum Given a set of candidate numbers (C) (without duplicates) and a target number (T), f ...

  6. [LeetCode] Three Sum题解

    Three Sum: Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? ...

  7. 01Two Sum题解

    Tow Sum 原题概述: Given an array of integers, return indices of the two numbers such that they add up to ...

  8. 【CF1445D】Divide and Sum 题解

    题目链接 题意简介 将一个长度为 2n 的数列平均分为两个子数列 p 和 q 后,p 按从小到大排序,q 按从大到小排序. 排序后,记 p 为 \(\{x_i\}\) ,q 为 \(\{y_i\}\) ...

  9. BZOJ3155:Preprefix sum——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3155 最朴素的想法是两棵树状数组,一个记录前缀和,一个记录前缀前缀和,但是第二个我们非常不好修改 ...

随机推荐

  1. 测试用例设计经典面试题之电梯、杯子、笔、桌子、洗衣机、椅子、ATM等

    测试用例设计经典面试题之电梯.杯子.笔.桌子.洗衣机.椅子.ATM等 1.测试项目:电梯 需求测试:查看电梯使用说明书.安全说明书等 界面测试:查看电梯外观 功能测试:测试电梯能否实现正常的上升和下降 ...

  2. 杂记:Linux下gcc升级

    公司要求,需要在CentOS6.5系统下进行一些测试.因为编写的测试程序中使用了一些C++11之后新增的特性,而CentOS6.5中安装的gcc版本为4.4.7,并不支持C++11,所以需要对gcc进 ...

  3. Flume 实战练习

    前期准备 了解Flume 架构及核心组件 Flume 架构及核心组件 Source : 收集(指定数据源从哪里获取) Channel : 聚集 Sink : 输出(把数据写到哪里去) 学习使用 Flu ...

  4. Mac 安装Android Studio 及环境变量配置

    我翻开历史一查,这历史没有年代.歪歪斜斜的每页上都写着"仁义道德"几个字,我横竖睡不着,仔细看了半夜,才从字缝里看出来,满本上都写着两个字"吃人"! –鲁迅&l ...

  5. 涉嫌垄断的App Store,到底做了什么让开发者暴怒

    ​ Store,到底做了什么让开发者暴怒" title="涉嫌垄断的App Store,到底做了什么让开发者暴怒"> ​什么行业最赚钱?不是你想象中的餐饮.互联网. ...

  6. iOS多线程之Thread

    多线程 • Thread 是苹果官方提供的,简单已用,可以直接操作线程对象.不过需要程序员自己管理线程的生命周期,主要是创建那部分 优缺点 面向对象,简单易用 直接操作线程对象 需要自己管理线程生命周 ...

  7. C++扬帆远航——13(个人所得税计算器)

    /* * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:shui.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  8. sublime 安装Anaconda插件 配置python开发环境

    我的sublime 3  python 3.6.6 安装Anaconda插件 由于Anaconda插件本身无法知道Python安装的路径,所以需要设置Python主程序的实际位置.选择Settings ...

  9. 全差分运算放大器ADA4930的分析(2)

    前面解释了在ADA4930组成的单端转差分电路的输入电阻RIN的大小,可知当RF=RG=1KΩ的时候,RIN=1.33KΩ. 图1单端转差分电路 如图1所示,假设信号源为2V VPP的信号,信号源的内 ...

  10. criteria.setCacheable(true);这个方法是干什么用的

    criteria.setCacheable(true); 一下是Criteria的底层源代码 /** * Enable caching of this query result, provided q ...