51nod 1115 最大M子段和 V3
生活随笔
收集整理的這篇文章主要介紹了
51nod 1115 最大M子段和 V3
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
環形最大M子段和,N個整數組成的序列排成一個環,a[1],a[2],a[3],…,a[n](a[n-1], a[n], a[1]也可以算作1段),將這N個數劃分為互不相交的M個子段,并且這M個子段的和是最大的。如果M >= N個數中正數的個數,那么輸出所有正數的和。 例如:-2 11 -4 13 -5 6 -1,分為2段,6 -1 -2 11一段,13一段,和為27。 ?收起
相比v2,改成首尾相接的,如果首尾同號就歸并。
代碼: #include <iostream> #include <cstdlib> #include <cstdio> #include <set> using namespace std; typedef long long ll; int n,m; ll d,last; ll s[100005]; int l[100005],r[100005]; int sc; void modify(int cur) {///修改左右相鄰結點的下標int ll = l[cur],rr = r[cur];r[ll] = rr;l[rr] = ll; } int main() {while(~scanf("%d%d",&n,&m)) {sc = last = 0;ll sum = 0,ans = 0,c = 0;set<pair<ll,int> > ss;for(int i = 0;i < n;i ++) {scanf("%lld",&d);if(d * last < 0) {s[++ sc] = sum;sum = d;}else sum += d;last = d;}if(sum) s[++ sc] = sum;if(s[1] > 0 && s[sc] > 0 || s[1] < 0 && s[sc] < 0) {s[1] += s[sc --];}for(int i = 1;i <= sc;i ++) {ss.insert(make_pair(abs(s[i]),i));c += s[i] > 0;ans += (s[i] > 0 ? s[i] : 0);l[i] = i - 1;r[i] = i + 1;}r[sc] = 1;l[1] = sc;while(c > m) {int cur = ss.begin() -> second;ss.erase(ss.begin());ans -= abs(s[cur]);s[cur] += s[l[cur]] + s[r[cur]];ss.erase(make_pair(abs(s[l[cur]]),l[cur]));modify(l[cur]);ss.erase(make_pair(abs(s[r[cur]]),r[cur]));modify(r[cur]);if(s[cur]) ss.insert(make_pair(abs(s[cur]),cur));c --;}printf("%lld\n",ans);}return 0; }
輸入
第1行:2個數N和M,中間用空格分隔。N為整數的個數,M為劃分為多少段。(2 <= N , M <= 100000) 第2 - N+1行:N個整數 (-10^9 <= a[i] <= 10^9)輸出
輸出這個最大和輸入樣例
7 2 -2 11 -4 13 -5 6 -2輸出樣例
26相比v2,改成首尾相接的,如果首尾同號就歸并。
代碼: #include <iostream> #include <cstdlib> #include <cstdio> #include <set> using namespace std; typedef long long ll; int n,m; ll d,last; ll s[100005]; int l[100005],r[100005]; int sc; void modify(int cur) {///修改左右相鄰結點的下標int ll = l[cur],rr = r[cur];r[ll] = rr;l[rr] = ll; } int main() {while(~scanf("%d%d",&n,&m)) {sc = last = 0;ll sum = 0,ans = 0,c = 0;set<pair<ll,int> > ss;for(int i = 0;i < n;i ++) {scanf("%lld",&d);if(d * last < 0) {s[++ sc] = sum;sum = d;}else sum += d;last = d;}if(sum) s[++ sc] = sum;if(s[1] > 0 && s[sc] > 0 || s[1] < 0 && s[sc] < 0) {s[1] += s[sc --];}for(int i = 1;i <= sc;i ++) {ss.insert(make_pair(abs(s[i]),i));c += s[i] > 0;ans += (s[i] > 0 ? s[i] : 0);l[i] = i - 1;r[i] = i + 1;}r[sc] = 1;l[1] = sc;while(c > m) {int cur = ss.begin() -> second;ss.erase(ss.begin());ans -= abs(s[cur]);s[cur] += s[l[cur]] + s[r[cur]];ss.erase(make_pair(abs(s[l[cur]]),l[cur]));modify(l[cur]);ss.erase(make_pair(abs(s[r[cur]]),r[cur]));modify(r[cur]);if(s[cur]) ss.insert(make_pair(abs(s[cur]),cur));c --;}printf("%lld\n",ans);}return 0; }
?
轉載于:https://www.cnblogs.com/8023spz/p/10912467.html
總結
以上是生活随笔為你收集整理的51nod 1115 最大M子段和 V3的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [19/05/26-星期日] JavaS
- 下一篇: shell初级-----控制脚本