简单的高效算法分析初步?

   
分析一个问题:

最大连续和的问题。给出长度为n序列A1,A2,...An求连续最大和;

对于一般的想法,可以给出下面的代码

t = 0;
best = A[1];
for(int i = 1; i <= n; i++)
  for(int j = i ; j <= n; j++)
{
int    sum = 0;
for ( int k = i ; k <= j; k++)
{
sum += A[K]; t++:
}
if(sum > best) best = sum;//更新最大值
}

采用的思想:幼儿园学生思想!!!!

这种算法好想但是需要经历一个三重循环

由于进行了三重循环,时间复杂度为N的三次方

对于推算时间复杂度:

()采取上界分析,最坏的情况是什么情况?对于三重循环最多也就是每个循环都进行N次,于是就推算出时间复杂度 T(n) = O(n^3);

在这种情况下,你一定要试着优化你的算法

于是我们可以使用一些优化:

S[0]  = 0;
for(int  i  = 1; i <=n; i+)  s[i]  = s[i-1] +A[i];//推进前缀
  for(int i = 1; i <=n; i++)
for(int j =i;  j  <=  n;  j++) best  = max(best  ,s[j]  - s[i-1]);
采用的思想:递推的思想!!!(初中生必备)

这样就可以进行一个一重循环+一个二重循环

()采用上界分析,最坏的情况也就是时间复杂度T(n) = O(n^2)

----------------------------------------------------------------------------------------------------------------------------------------------------(难度增加分割线)

使用分治法来解决问题

(1) 划分问题 : 把问题的实例划分成子问题

(2)递归求解 : 递归解决子问题

(3)合并问题 : 合并子问题得到原问题的解

划分:把序列中的元素分成元素数量尽量可能相等的两半;
递归求解:分别求出位于左半或者位于右半的最佳序列
合并:求出起点位于左半、终点位于右半的的最大连续序列,并和子问题的最优解比较
#include<bits/stdc++.h>

using namespace std;
int maxsum(int *s, int x, int y)
{
    int  v,left,right,mmax;
    if(y - x == 1)
    {
        return s[x];
    }
    int m = x +(y - x) /2;//尽可能中间的数
    mmax = max(maxsum(s,x,m),maxsum(s,m,y));//递归求解
    v =  0;
    left = s[m-1];
    for(int i = m-1 ; i>= x; i--)
    {
        left = max(left,v += s[i]);
    }
    v = 0;
    right = s[m];
    for(int i = m; i < y; i++)
    {
        right = max(right, v += s[i]);
    }
    return max(mmax,left+right);//感觉向前走???

}
int main()
{
    int n;
    int s[10000];
    cin>>n;
    for(int i = 0 ;i < n; i++)
    {
        cin>>s[i];
    }
    int m;
    m = maxsum(s,0,n);
    cout<<m<<endl;


    return 0;
}
递归求解思想(大学生正常思维)
附上全代码!感觉就像切水出波一样,在每次切完的中间再切 这样求解时间复杂度T(n) = O(n*logn)





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值