高效算法设计_算法分析初步(最大连续和)

来源:互联网 发布:mac如何关闭dashboard 编辑:程序博客网 时间:2024/05/19 22:56

算法分析初步

渐进时间复杂度

基本操作的数量往往可以写成关于“输入模式二”的表达式,保留最大象并忽略系数后的表达式称为算法的渐进时间复杂度。

最大连续和

友情链接:六种姿势拿下最大序列和 嗯。。以下就够折腾了。我觉得第四种最重要,最重要,最重要!

题目:给出一个长度为n的序列A1,A2,…..,An,求最大连续和。

输入:

6-2 11 -4 13 -5 -2

输出:

20

1 O(n^3)

使用三次循环,计算每一个序列和的大小,然后和best=A[1]进行比较。

#include <stdio.h>#define MAXN 10000int A[MAXN];int main() {    int tot,i,j,k,best,sum,n;    scanf("%d",&n);    for(i=1;i<=n;i++)scanf("%d",&A[i]);    tot=0;    best=A[1];    for(i=1;i<=n;i++){        for(j=i;j<=n;j++){            int sum=0;            for(k=i;k<=j;k++){                sum+=A[k];                tot++;            }            if(sum>best) best=sum;        }    }    printf("%d\n",best);    return 0;}

2 O(n^2)

利用“连续的序列和等于两个前缀和之差”,计算每个前缀和之差。将三次循环简化为两个循环。

#include <stdio.h>#define MAXN 10000int A[MAXN],s[MAXN];int main(){    int tot,i,j,k,best,sum,n;    scanf("%d",&n);    for(i=1;i<=n;i++)scanf("%d",&A[i]);    best=A[0];    s[0]=0;    for(i=0;i<=n;i++) s[i]=s[i-1]+A[i];    for(i=1;i<=n;i++)        for(j=i;j<=n;j++)/*          best>?=s[j]-s[i-1];>?=是不是很神奇,嗯,如果大于的话就不变,小于的话就赋值。也就是取这个循环的最大值 */        {            if(best<(s[j]-s[i-1]))                best=s[j]-s[i-1];        }    printf("%d\n",best);    return 0;}

3 分治法O(nlog(n))

递归求解:递归求解子问题;合并问题:合并子问题的解得到原问题的解。

分治法是个什么鬼

分治法在每一层递归上都有三个步骤:
分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;
解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题;
合并:将各个子问题的解合并为原问题的解。

#include <stdio.h>#define MAXN 10000int A[MAXN];int maxsum(int *A,int x,int y){    int i,m,v,L,R,max;    if(y-x==1) return A[x];    m=x+(y-x)/2;//第一步,确定二分的分界点,注意注意注意!!!    /*     "/"计算的“取整”是朝零方向的取整,而不是向下取整     */    max=maxsum(A,x,m)>?maxsum(A,m,y);//第二步,递归求解 不大于就赋值    v=0;L=A[m-1];   //第三步,合并(1)从分界点开始往左的最大连续和L    for(i=m-1;i>=x;i--){        v+=A[i];        if(L<v) L=v;    }//如果小于等于的话就赋值,L求出前半部分序列和的最大值    v=0;R=A[m]; //第三步,合并    for(i=m;i<y;i++){        v+=A[i];        if(R<v) R=v;    }   //同上。R求出后半部分序列和的最大值    return max>?(L+R);//把问题的解与L和R比较}int main() {    int n;    scanf("%d",&n);    for(int i=1;i<=n;i++)scanf("%d",&A[i]);    int t=maxsum(A,1,n+1);    printf("%d\n",t);    return 0;}

4 动态规划法O(n)

#include <stdio.h>#define MAXN 10000int A[MAXN];int n;int maxSubSequeue(int *A){    int ThisSum,MaxSum,j;    ThisSum=0,MaxSum=-1000000;    for(j=1;j<=n;j++){        ThisSum+=A[j];        if(ThisSum>MaxSum)            MaxSum=ThisSum;//最后只与MaxSum有关        if(ThisSum<0) ThisSum=0;//一旦发现小于0,则归0.    }    return MaxSum;}int main() {    scanf("%d",&n);    for(int i=1;i<=n;i++)scanf("%d",&A[i]);    int t=maxSubSequeue(A);    printf("%d\n",t);    return 0;}
原创粉丝点击