HDUOJ-1003 Max Sum(最大子序列和)(动态规划)
2016-04-30 14:48
363 查看
O(n)算法
首先,引用一个前人造好的轮子,此轮子来自《数据结构与算法分析-C语言描述》图2.8:int MaxSubsequenceSum(const int A[],int N) { int ThisSum,MaxSum,j; ThisSum = MaxSum = 0; for(j=0;j<N;j++) { ThisSum += A[j]; if(ThisSum > MaxSum) MaxSum = ThisSum; else if(ThisSum < 0) ThisSum = 0; } return MaxSum; }
对于此算法可以作此理解:
对于(0-N)的每个(A[j]-A
),都做一次累加,将每次累加的结果做一次判断(小于零则舍弃),大于MaxSum则统计到MaxSum里,则N次循环内,必然会有一个最优解被更新为MaxSum的值。
状态转移方程为:
dp[i] = max{ dp[i-1]+A[i] , A[i] }
考虑到结尾并不需要每一个dp[i] , 其实用两个变量代替就可以:ThisSum = max{LastSum+A[i] , A[i]}
本题的要求同时输出最大子序列的上界和下界,需要几个变量来统计。改造后的完整代码为:
/* * Created by zsdostar in 2016/4/30 */ #include<iostream> using namespace std; int start,endd; int startm,endm; int ThisSum,LastSum; int maxx = -2147483648; int MaxSubSequence(int arr[],int n) { for(int i=0;i<n;i++) { if(LastSum>=0) { ThisSum = LastSum + arr[i];endd = i; } else { ThisSum = arr[i];start = endd = i; } if(maxx<=ThisSum) { maxx = ThisSum; startm = start;endm = endd; } LastSum = ThisSum; } return maxx; } int main() { int count,len; int array[100001]; cin>>count; for(int flag=1;flag<=count;flag++) { cin>>len; for(int i=0;i<len;i++) cin>>array[i]; start = endd = 0,maxx = -1001; startm = endm = 0; ThisSum = LastSum = 0; cout<<"Case "<<flag<<":"<<endl<<MaxSubSequence(array,len); cout<<" "<<startm+1<<" "<<endm+1<<endl; if(flag<count) cout<<endl; } return 0; }
关于本题有两个问题:
-目前的轮子通过大于小于0来判定是否更新状态,那么如果整个数组全都是负数,或者正数数量等于1,那么结果是错的-HDU1003的测试数据也没有考虑问题1,导致考虑不全的代码也能通过
下次复习这道题的时候解决这个问题,更新考虑更全面的代码。
相关文章推荐
- 华为2016年校园招聘上机笔试题(2)----简单错误记录
- maven生命周期(转)
- DevicePolicyManager类的使用
- Maven2和MyEclipse插件
- [UVa 11426] GCD - Extreme (II) (数论 + 脑洞 + 技巧)
- 十、森林与并查集---(6)并查集路径压缩优化
- Unity3d生命周期
- JDK7文件处理
- empty与isset的用法及区别(转载)
- 怎样高效阅读源码?
- C - How Many Tables——HOJ
- 【LeetCode】Excel Sheet Column Number 解题报告
- linux设置可以在当前目录查找可执行文件的方法
- 负载均衡的基本算法
- 百度地图 API 使用
- 父子窗口之间的调用
- 自定义可拖拽的view
- Android群英传笔记——第十章:Android性能优化
- 向有序的环形单链表中插入新节点
- Android群英传笔记——第十章:Android性能优化