日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【计蒜客 - 蓝桥训练】蒜厂年会(单调队列优化dp,循环数列的最大子段和)

發(fā)布時間:2023/12/10 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【计蒜客 - 蓝桥训练】蒜厂年会(单调队列优化dp,循环数列的最大子段和) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題干:

在蒜廠年會上有一個抽獎,在一個環(huán)形的桌子上,有?nn?個紙團,每個紙團上寫一個數(shù)字,表示你可以獲得多少蒜幣。但是這個游戲比較坑,里面竟然有負數(shù),表示你要支付多少蒜幣。因為這些數(shù)字都是可見的,所以大家都是不會出現(xiàn)的賠的情況。

游戲規(guī)則:每人只能抓一次,只能抓取一段連續(xù)的紙團,所有紙團上的數(shù)字和就是你可以獲得的蒜幣。

蒜頭君作為蒜廠的一員在想,我怎么可以獲得最多的蒜幣呢?最多能獲取多少蒜幣呢?

因為年會是發(fā)獎,那么一定有大于?00?的紙團。

輸入格式

第一行輸入一個整數(shù)?nn,表示有?nn?個紙團。

第二行輸入輸入?nn?個整數(shù)?a_iai?,表示每個紙團上面寫的數(shù)字(這些紙團的輸入順序就是環(huán)形桌上紙團的擺放順序)。

輸出格式

輸出一個整數(shù),表示蒜頭君最多能獲取多少蒜幣。

數(shù)據(jù)范圍

對于?30\%30%?的數(shù)據(jù):1 \le n \le 10^2,-10^3 \le a_i \le 10^31≤n≤102,?103≤ai?≤103。

對于?60\%60%?的數(shù)據(jù):1 \le n \le 5 \times 10^3,-10^6 \le a_i \le 10^61≤n≤5×103,?106≤ai?≤106。

對于?100\%100%?的數(shù)據(jù):1 \le n \le 10^5,-10^9 \le a_i \le 10^91≤n≤105,?109≤ai?≤109。

樣例輸入復制

3 1 -2 1

樣例輸出復制

2

解題報告:

? 單調(diào)隊列優(yōu)化dp。

AC代碼:

#include <bits/stdc++.h> using namespace std; typedef long long LL; const int INF = 0x3f3f3f3f; const LL mod = 1e9 + 7; const int N = 200005; int a[N]; LL pre[N]; int main() {int n;scanf("%d", &n);for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);a[n + i] = a[i];}for (int i = 1; i <= 2 * n; i++) {pre[i] = pre[i - 1] + a[i];}deque<int> q;q.push_back(0);LL ans = a[1];for (int i = 1; i <= 2 * n; i++) {if (!q.empty() && q.front() < i - n) {q.pop_front();}ans = max(ans, pre[i] - pre[q.front()]);while (!q.empty() && pre[q.back()] >= pre[i]) {q.pop_back();}q.push_back(i);}printf("%lld\n", ans);return 0; }

WA代碼:(只通過60%)

#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair #define fi first #define se second using namespace std; const int MAX = 2e5 + 5; ll a[MAX],dp[MAX],dpp[MAX]; int main() {int n;cin>>n;for(int i = 1; i<=n; i++) cin>>a[i];ll sum = 0 ;for(int i = 1; i<=n; i++) {if(sum >=0) sum += a[i],dp[i] = sum;else sum = a[i],dp[i] = sum;}for(int i = 1; i<=n; i++) {if(sum >=0) sum += a[i],dpp[i] = sum;else sum = a[i],dpp[i] = sum;}cout << max(*max_element(dp+1,dp+n+1),*max_element(dpp+1,dpp+n+1));return 0 ;}

最暴力的做法:(肯定會T的)

#include <bits/stdc++.h> using namespace std; typedef long long LL; const int INF = 0x3f3f3f3f; const LL mod = 1e9 + 7; const int N = 200005; int a[N]; LL pre[N]; int main() {int n;scanf("%d", &n);for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);a[n + i] = a[i];}LL ans = a[1];for (int i = 1; i <= n; i++) {LL sum = 0;for (int j = i; j < i + n; j++) {sum += a[j];if (sum > ans) {ans = sum;}}}printf("%lld\n", ans);return 0; }

另一個做法:

https://blog.csdn.net/weixin_41544329/article/details/85076111

總結(jié)

以上是生活随笔為你收集整理的【计蒜客 - 蓝桥训练】蒜厂年会(单调队列优化dp,循环数列的最大子段和)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。