• CF33C Wonderful Randomized Sum 题解


    CSDN同步

    原题链接

    简要题意:

    你可以无限次的把该数组的一个前缀和后缀 ( imes -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
    ",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
    ",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
    ",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 imes C - S ]

    显然让 (C) 越大越好。

    那答案不就摆在面前了?

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

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

    [ exttt{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
    ",ans*2-s);	
    	return 0;
    }
    

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

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

    max(a[1],0)
    

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

    算法五

    终于算是拨云见雾了,结果在临近 ( exttt{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
    ",ans*2-s);	
    	return 0;
    }
    

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

  • 相关阅读:
    登陆界面
    信号和槽
    线程同步
    java script简介
    css粘性定位sticky的使用
    vue中使用qrcodejs2生成二维码
    webpack基本使用
    总结一些h5出现的问题及解决方案
    srcset属性配合w宽度描述符配合sizes属性
    vw实现页面布局
  • 原文地址:https://www.cnblogs.com/bifanwen/p/12546146.html
Copyright © 2020-2023  润新知