您的位置:首页 > 其它

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)的算法。

#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;
}
今天自行车竟然被偷了,真不爽啊!!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐