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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【51nod - 1065】 最小正子段和( 前缀和排序 )

發(fā)布時(shí)間:2023/12/10 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【51nod - 1065】 最小正子段和( 前缀和排序 ) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題干:

N個(gè)整數(shù)組成的序列a11,a22,a33,…,ann,從中選出一個(gè)子序列(aii,ai+1i+1,…ajj),使這個(gè)子序列的和>0,并且這個(gè)和是所有和>0的子序列中最小的。

例如:4,-1,5,-2,-1,2,6,-2。-1,5,-2,-1,序列和為1,是最小的。

Input

第1行:整數(shù)序列的長(zhǎng)度N(2 <= N <= 50000)?
第2 - N+1行:N個(gè)整數(shù)

Output

輸出最小正子段和。

Sample Input

8 4 -1 5 -2 -1 2 6 -2

Sample Output

1

題目大意:

? 中文題不解釋啦。

解題報(bào)告:

? ? 法一:可以用結(jié)構(gòu)體保存一個(gè)前綴和,然后對(duì)前綴和排序,可以證明,答案就在相鄰的兩個(gè)排序中。當(dāng)然,要滿足輸入順序不能改變,即node[i].pos > node[i-1].pos && node[i].sum > node[i-1].sum ?這兩個(gè)條件都需要滿足。并且 這里pos放在結(jié)構(gòu)體里,并且?guī)е@個(gè)pos排序,不能求完前綴和然后用pos數(shù)組存sum[i]出現(xiàn)的位置,因?yàn)榭赡苡卸鄠€(gè)sum[i]是同一個(gè)值,會(huì)重疊,而且此法不能去重,所以需要帶著pos這個(gè)值排序。 還有一個(gè)細(xì)節(jié),這里的排序必須從node開(kāi)始排序而不是node+1 ?!也很好理解,因?yàn)榇鸢敢部赡芫褪禽斎氲膕um[i]前綴和,所以sum[i] - sum[0]也可能是答案啊!還有就是,注意這題需要longlong。

? ?法二:可以用線段樹(shù)。

?

附一個(gè)題解:

將前n項(xiàng)和求出來(lái)并排序,然后比較相鄰兩項(xiàng)其位置關(guān)系,如果可以組成序列,則說(shuō)明其可能是所要求結(jié)果,然后從所有可能是結(jié)果的結(jié)果中取出最小值即可。?
如:

排序前

sum4386571311
pos12345678

排序后

sum3456781113
pos21546387

如果ABC為排序后的結(jié)果,那么當(dāng)A和B不能組成序列,而A和C可以組成序列時(shí),那么B和C一定可以組成序列,并且BC一定會(huì)比AC更優(yōu)。鏈接

AC代碼:(前綴和排序)

#include<bits/stdc++.h> using namespace std; const int MAX = 50000 + 5; int a[MAX]; int n; struct Node {int pos,val;long long sum; } node[MAX]; bool cmp(Node a,Node b){return a.sum < b.sum; } int main() {cin>>n;for(int i = 1; i<=n; i++) {scanf("%d",&node[i].val);node[i].pos = i;node[i].sum = node[i-1].sum + node[i].val;} // for(int i = 1; i<=n; i++) { // printf("%d %d %d %d\n",i,node[i].pos,node[i].sum,node[i].val); // }// printf("\n");sort(node,node+n+1,cmp); // for(int i = 1; i<=n; i++) { // printf("%d %d %d %d\n",i,node[i].pos,node[i].sum,node[i].val); // }long long minn = 0x3f3f3f3f3f3f3f3f;int flag = 1;int pos = 1;while(node[pos].pos < node[pos - 1].pos) pos++;for(int i = 1; i<=n; i++) {if(node[i].pos > node[i-1].pos && node[i].sum > node[i-1].sum) {minn = min(minn,node[i].sum - node[i-1].sum);}}printf("%lld\n",minn);return 0 ; }

法二:用set維護(hù)一下。?

?

總結(jié)

以上是生活随笔為你收集整理的【51nod - 1065】 最小正子段和( 前缀和排序 )的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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