生活随笔
收集整理的這篇文章主要介紹了
最长连续子序列变种
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在蒜廠年會上有一個抽獎,在一個環形的桌子上,有 n 個紙團,每個紙團上寫一個數字,表示你可以獲得多少蒜幣。但是這個游戲比較坑,里面竟然有負數,表示你要支付多少蒜幣。因為這些數字都是可見的,所以大家都是不會出現的賠的情況。
游戲規則:每人只能抓一次,只能抓取一段連續的紙團,所有紙團上的數字和就是你可以獲得的蒜幣。
蒜頭君作為蒜廠的一員在想,我怎么可以獲得最多的蒜幣呢?最多能獲取多少蒜幣呢?
因為年會是發獎,那么一定有大于 0 的紙團。
輸入格式
第一行輸入一個整數 n,表示有 n 個紙團。
第二行輸入輸入 n 個整數 ai表示每個紙團上面寫的數字(這些紙團的輸入順序就是環形桌上紙團的擺放順序)。
輸出格式
輸出一個整數,表示蒜頭君最多能獲取多少蒜幣。
只過了6組數據:https://paste.ubuntu.com/p/Fc6xmf8F7Z/
本題成環了,連續的子序列最大值,當不成環的時候,取得最大值的時候可能在中間的連續部分,在當成環之后,就多了一種在兩端的可能,那么這種連續子序列的最大值求法就可以用總和減去中間最小的連續子序列的和。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6;
ll a[maxn];
ll dp_max[maxn];
ll dp_min[maxn];
int main(){
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);int n;while(scanf("%d",&n)!=EOF){ll sum=0;for(int i=1;i<=n;++i){scanf("%lld",&a[i]);sum+=a[i];}ll MAX=-maxn;ll MIN=maxn;dp_min[0]=dp_max[0]=0;for(int i=1;i<=n;++i){MAX=max(MAX,dp_max[i]=max((ll)0,max(a[i],dp_max[i-1]+a[i])));MIN=min(MIN,dp_min[i]=min((ll)0,min(a[i],dp_min[i-1]+a[i])));}cout<<max(MAX,sum-MIN)<<endl;}return 0;
}
?
總結
以上是生活随笔為你收集整理的最长连续子序列变种的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。