最小子段和,最大子段和,最小正子段和

来源:互联网 发布:iphone7必备软件推荐 编辑:程序博客网 时间:2024/05/29 02:48

最大子段和比较好求解,就是一个dp标记走就可以了,当dp<0,让dp等于当前位,dp大于0就加上当前位就好。


最小子段和就是把所有的元素去相反数,然后在此基础上求一个最大子段和就好。


主要想说的是最小正子段和的求法,是先算前i位的累加和dp[i],并记录标记为i。

然后对所有的dp[i]进行小到大的排序,然后对两个相连的dp[i],如果后者的标记大于前者的标记,那么它们的差值是候选答案,然后选取候选答案最小的那个。

PS:注意要在里面加一个标记为-1的,和为0的节点。

#include <iostream>#include <algorithm>#include <cmath>using namespace std;/***********************51nod 1065最小正子段和***********************/struct Node{__int64 val, flag;};Node node[50005];__int64 N, num[50005];bool comp(Node a, Node b){if(a.val == b.val)return a.flag > b.flag;return a.val < b.val;}int min(int a, int b){if(a < 0) return b;return a < b ? a : b;}void solve(){for(int i = 0; i < N; i ++)cin>>num[i];//将每一项进行累加操作node[0].flag = -1, node[0].val = 0;for(int i = 1; i <= N; i ++){node[i].flag = node[i - 1].flag + 1;node[i].val = node[i - 1].val + num[i - 1];}//然后进行排序sort(node, node + N + 1, comp);int ans = -1;//当排序后,相连两项,它的后面一项的标记大于前面一项的标记时,它是候选答案之一,进行<span style="white-space:pre"></span>//比较即可,注意加上一项为0的for(int i = 1; i <= N; i ++){if(node[i].flag > node[i - 1].flag){if(node[i].val - node[i - 1].val > 0)ans = min(ans, node[i].val - node[i - 1].val);}}cout<<ans<<endl;}int main(){while(cin>>N){solve();}}


0 0
原创粉丝点击