最小子段和,最大子段和,最小正子段和
来源:互联网 发布: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
- 最小子段和
- 最小子段和,最大子段和,最小正子段和
- 最大子段和(51Nod 1049)、最小正子段和(51Nod 1065)、总结(最小子段和、最大子段和、最小正子段和)
- 51Nod-1050 循环数组最大段和【最大子段和+最小子段和+DP】
- 最大子段和
- 最大子段和
- 最大子段和
- 最大子段和
- “最大子段和”
- 最大子段和
- 最大子段和
- 最大子段和
- 最大子段和
- 最大子段和
- 最大子段和
- 最大子段和
- 最大子段和
- 最大子段和
- thinkphp中session设置session周期无效
- 天地图瓦片下载及解析
- OC_05_03
- 三星手机下载管理器已禁用解决方案
- 扩展:datagrid鼠标经过提示单元格内容
- 最小子段和,最大子段和,最小正子段和
- 备注
- aerospike init
- Android UI中遇到的问题
- mac上管理多个终端窗口
- adb无法启动
- 监理工程师岁月--权力的诱惑
- ORACLE 运用RMAN删除过期备份和日志文件 释放空间
- 大三自动化单片机实验总结