簡要題意:
你可以無限次的把該數組的一個前綴和後綴 ,問最終的最大序列和。
這題盲目WA了數次才知道本質
這題89個數據吊打std
CF真好啊,發現一個錯後面就不測了
下面,就以我艱辛的思維歷程來構造本篇博客。
算法一
盲猜:所有數都可以變成正數。
然後絕對值相加。
連樣例也沒測。
然後,. 只過了前兩個樣例,第三個就死了。
#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;
}
交上去,發現得了 分。
發現 有點問題。
算法三
?然後加了幾個等號。
#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;
}
然後得了 分。
我卻,我答案是負數,它答案是正數
算法四
真正感到自己 腦抽了 挺堅強的。
其實呢,我們還是要重視它,畢竟是 嗎。(其實也不難)
你想,比方說前一段是 ,後一段是 ,重疊是 ,一共是 .()
(指前綴、後綴、重疊部分、總部分的和)
此時答案爲:
然而:
(這是因爲,中間一段經過兩次之後沒變,所以還是加上)
所以答案變形爲:
顯然讓 越大越好。
那答案不就擺在面前了?
Dev-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;
}
看上去沒啥問題,然後得了 .
原因: 的初值應該是:
max(a[1],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,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;
}
終於 了。時間複雜度:.