原题链接

简要题意:

你可以无限次的把该数组的一个前缀和后缀 \(\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. Linux sed && awk

    sed sed -i '/exit 0/i\ip route add 10.0.0.0/8 via '$gateway_ip'' /etc/sysconfig/network-scripts/ifup ...

  2. Excel技巧:如何绘制一份优秀的甘特图(项目管理)

    作者:秦路,天善智能特约专家.资深数据分析师,数据化运营专家.擅长结合运营和数据,建立数据化运营体系. 个人公众号:秦路(微信ID:tracykanc) 今天我给大家分享的内容是如何利用Excel绘制 ...

  3. 先治再扶,重灾区后的P2P你还敢投吗?

    ​ 互联网强大的包容性和创新性,给予很多新生事物成长的空间.而其全面普及与快速传播的特性,也让任何事物都像被放在放大镜乃至显微镜下,几乎无形遁形.这样一来,新生事物很容易被"神化" ...

  4. OpenCV读一张图片并显示

    Java 版本: JavaCV 用OpenCV读一张图片并显示.只需将程序运行时的截图回复.如何安装配置创建项目编写OpenCV代码,可参考何东健课件和源代码或其他资源. package com.gi ...

  5. kali linux下运行.sh文件权限不够解决办法

    我要装一个生成免杀的神奇,系统提示权限不够 2 于是我想到了sudo,可还是不行 3 于是找到了方法 chmod   a+x   文件名 4 再运行一下,成功 5 有时有的方法很简答,只要你愿意找.

  6. vue——一个页面实现音乐播放器

    请忽略下面这段文字年关将至,时间好歹又多出了些许.却不敢过度消遣.岁月未曾饶过我,我亦不想饶过岁月.且将它塞得膨胀,让这一年看似加更充实.不曾料想我一个爱些风花雪月.研墨行歌之人,却做起了碼农这一行当 ...

  7. JZOJ 1349. 最大公约数 (Standard IO)

    1349. 最大公约数 (Standard IO) Time Limits: 1000 ms Memory Limits: 65536 KB Description 小菜的妹妹小诗就要读小学了!正所谓 ...

  8. ubuntu1804自带的vim和vi都是用什么版本?

    之前搜索vim一些命令时,经常看到有人说ubuntu自带的vim是是vim.tiny的,功能不全. 什么需要先卸载,再重装,真的是这样吗? 我查了一下,vim的版本号 vim --version vi ...

  9. 黑科技神器-uTools

    Hello,各位小伙伴们好,又到周末了,小黑哥给大家分享一款神器:『utools』. 官网地址:https://u.tools/ uTools 是一个极简.插件化.跨平台的现代桌面软件.通过自由选配丰 ...

  10. 本地Hadoop集群搭建

    什么是Hadoop? Hadoop是一个开源的Apache项目,通常用来进行大数据处理. Hadoop集群的架构: master节点维护分布式文件系统的所有信息,并负责调度资源分配,在Hadoop集群 ...