hdu1003 Max sum&hdu1231 最大连续上升子序列
2014-12-06 13:58
337 查看
大一时随便水题时碰到了hdu1003,大抵是初学,看了别人的代码后来自己也A掉了,但是没有了解思想。现在看来又有了新的收获。
这应该是刘汝佳的一道将算法复杂度的例题,给出了分治O(nlogn),预处理O(n^2),朴素O(n^3)的算法并进行比较。
题目大意是给出一串数字a[1]~a
,要求出这串数字中和最大的子串a[i]+..a[j],并输出i,j。
分治算法没去看,先给出O(n^2)的算法。
TLE了,必须优化才行,换了另一种方法,不知道是不是属于动态规划,反正是有一点那种思想在里面。
基本思想就是一边扫描数组一边更新max。
这是之前的一道题目,然后最近看到的hdu1231其实就是一样的思路。
下面给上hdu1231的AC代码:
这应该是刘汝佳的一道将算法复杂度的例题,给出了分治O(nlogn),预处理O(n^2),朴素O(n^3)的算法并进行比较。
题目大意是给出一串数字a[1]~a
,要求出这串数字中和最大的子串a[i]+..a[j],并输出i,j。
分治算法没去看,先给出O(n^2)的算法。
#include <iostream> #include <cstdio> using namespace std; const int max_n=99999; int sum[max_n]; int pre[max_n]; int main() { int ncase,n,max; scanf("%d",&ncase); for(int ii=1;ii<=ncase;ii++) { scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%d",&pre[i]); sum[0]=0; for(int i=1; i<=n; i++) sum[i]=sum[i-1]+pre[i]; max=pre[1]; int l=pre[1]; int r=pre ; for(int i=1; i<=n; i++) for(int j=1; j<=i; j++) if(sum[i]-sum[j-1]>max) { max=sum[i]-sum[j-1]; l=j; r=i; } printf("Case %d:\n",ii); printf("%d %d %d\n",max,l,r); if(ii!=ncase) printf("\n"); } return 0; }预处理原始pre,求出sum数组,显然题目最后的复杂度是O(n^2).
TLE了,必须优化才行,换了另一种方法,不知道是不是属于动态规划,反正是有一点那种思想在里面。
基本思想就是一边扫描数组一边更新max。
#include<stdio.h> void main() { int T,ncase,num; int start,stemp,end,etemp; int max,sum,i; int c[100002]; scanf("%d",&T); for(ncase=1;ncase<=T;ncase++) { scanf("%d",&num); for(i=1;i<=num;i++) scanf("%d",&c[i]); max=-1010; sum=0; start=1; stemp=1; for (i = 1; i <= num; i++) { sum=sum+c[i]; if(sum>max) {max=sum;start=stemp;end=i;} if(sum<0) {sum=0;stemp=i+1;} } printf("Case %d:\n",ncase); printf("%d %d %d\n",max,start,end); if(ncase!=T) printf("\n"); } }
这是之前的一道题目,然后最近看到的hdu1231其实就是一样的思路。
下面给上hdu1231的AC代码:
#include<stdio.h> #include<iostream> using namespace std; int main() { int num; int start,stemp,end; int max,sum,i; int c[100002]; while(scanf("%d",&num)==1) { if(num==0) break; for(i=1;i<=num;i++) scanf("%d",&c[i]); max=-1010; sum=0; start=1; stemp=1; for (i = 1; i <= num; i++) { sum=sum+c[i]; if(sum>max) {max=sum;start=stemp;end=i;} if(sum<0) {sum=0;stemp=i+1;} } if(max<0) { max=0; start=1; end=num; } printf("%d %d %d\n",max,c[start],c[end]); } return 0; }今天自行车竟然被偷了,真不爽啊!!!!
相关文章推荐
- ACMSTEP 3.2.1 && HDU1003 Max Sum //DP 最大字段和
- hdu 3415 Max Sum of Max-K-sub-sequence 单调队列 求连续l(1<=l<=k)个数的和的最大值 数列可循环
- Max_Sum_of_Sub_Array 连续子数组和最大
- hdu 1024 Max Sum Plus Plus 一串数字中,m段连续数字最大和 滚动数组+dp
- hdu3308 LCIS--区间更新 & 最长连续上升子序列
- hdu 1024 Max Sum Plus Plus(DP->k段连续区间的最大和)
- 【m段最大连续子段和的和】HDU - 1024 Max Sum Plus Plus
- 【HDU1024】Max Sum Plus Plus (m个不相交连续子列的最大和)
- HDU 1024 Max Sum Plus Plus求前n个数中的若干个数分为连续的m段的最大和值(解析)
- HDU - 1024 Max Sum Plus Plus (多段最大连续和+状态压缩)
- 有一个数组,让找到两个不重复的连续子序列A,B ,求Max(Sum(A)-Sum(B)。
- hdu1003 1024 Max Sum&Max Sum Plus Plus【基础dp】
- hdoj Max Sum Plus Plus 1024 (DP) m个连续数组最大和
- POJ 2479 Maximum sum & POJ 2573 Max Sequence (DP,最大连续子串和)
- HDU - 1024 Max Sum Plus Plus(最大M段连续子段和,详细解释)
- 最长上升子序列&最大上升子序列和
- Hdu 1025 Constructing Roads In JGShining's Kingdom 最大上升子序列nlogn算法
- hdoj Max Sum Plus Plus Plus 1244 (DP)m个连续段的最大和
- HDU 3415 Max Sum of Max-K-sub-sequence(单调队列+最大连续子串和)
- 单调队列的一个应用——求解连续区间最大值(HDU Max Sum of Max-K-sub-sequence)