您的位置:首页 > 其它

动态规划-最大子串 HDOJ1003

2013-11-04 21:43 288 查看
题目大意:输入是具有n个整数的向量x,输出是输入向量的任何联系子向量中的最大和,并输出该子向量的开始和结束为止。例如:

输入:

5 6 -1 5 4 -7

7
0 6 -1 1 -6 7 -5

输出:

Case 1:14 1 4

Case 2:7 1 6

分别有四种方法都能够求解出来分别是O(n^3)和O(n^2)以及O(n)但是只有分治算法和扫描算法能够AC,前两种都会超时。《编程珠玑》里面在第八章讲这个问题时有一句经典的话:任何正确的算法都必须至少花费O(n)的时间,所以最后的扫描算法已经很高效了,不需要优化了。

扫描算法代码如下复杂度O(N):

//time:328MS  mem:548k

#include <iostream>

using namespace std;

int main()
{
int T;
cin>>T;
short a[100002];
for(int k=1;k<=T;k++)
{
int n,locl,locr,max,ssum;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];

max = a[1];
ssum = 0;
locl = 1;
locr = 1;
int temp = 1;
for(int i=1;i<=n;i++)
{
ssum += a[i];

if(ssum>max)
{
max = ssum;
locl = temp;
locr = i;
}
if(ssum<0)
{
ssum = 0;
temp = i+1;
}

}

cout<<"Case "<<k<<":"<<endl;
cout<<max<<" "<<locl<<" "<<locr<<endl;
if(k<=T-1)
cout<<endl;

}
return 0;
}


平法算法(O(n^2)运行时会超时:

#include <iostream>

using namespace std;

int main()
{
int T;
cin>>T;
short a[100002];
short sum[100002];
for(int k=1;k<=T;k++)
{
int n;
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>a[i];
}
sum[0]=0;
sum[1] = a[1];
for(int j=2; j<=n;j++)
sum[j] = a[j]+sum[j-1];

int max = a[0];
int ssum;
int locl=0,locr=0;
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
ssum = sum[j]-sum[i-1];
if(ssum>max)
{
max = ssum;
locl = i;
locr = j;
}
}
}
cout<<"Case "<<k<<":"<<endl;
cout<<max<<" "<<locl<<" "<<locr<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: