若干算法实例总结

来源:互联网 发布:淘宝消保30元怎么交 编辑:程序博客网 时间:2024/05/16 10:51

1. 最大连续子序列

问题及分析: 给定一个数组a[n],求a的连续字数组中,使得该子数组的和最大,并给出和的值。

方法1: 暴力法,三重循环, 时间复杂度O(n^3)

方法2:分治法,可达到O(n*logn) 还不够好。。。

下面两种方法均可达到O(n)

O(n)方法 1  分析法: 

思路:一次遍历求出i的前缀和sum[i],

    记录每个i对应的min[i](即sum[0,1 2 ....i-1]中最小的一个)

    submax[i]  = sum[i] - min[i]可求得以每个a[i]结尾的最大子数组的值 

    比较submax[i] 可求得最大值max

      注意此时最大值未考虑每个sum[i], 遍历一遍比较得到真正最大子数组值

总结: 前缀和思路很多时候用的上,要考虑到,开拓思路; 注意不要忘记比较sum[i]

参考题目:

pat 

01-复杂度1. 最大子列和问题(20)

AC 代码
#include<cstdio>#include<algorithm>using namespace std;int main(){int N,a[100000],sum[100000],submax[100000],m[100000],max;scanf("%d",&N);for(int i = 0; i < N;i++){scanf("%d",&a[i]);}sum[0] = a[0];submax[0] = a[0];m[0] = 100000000;m[1] = sum[0];max = a[0];for(int i = 1; i < N;i++){sum[i] = sum[i-1] +a[i];m[i] = min(m[i-1], sum[i-1]);submax[i] = sum[i] - m[i];if(submax[i] > max){max = submax[i];}}for(int i = 0; i < N; i++){if(sum[i] > max){max = sum[i];}}printf("%d",max);return 0;} 
O(n) 方法2 :动态规划

思路:submax[i] = max(submax[i-1], a[i)) 求最优子问题(以a[i]结尾的最大子数组和)

            动态规划典型问题

AC 代码

#include<cstdio>int main(){int N,a[100000],submax[100000],max;scanf("%d",&N);for(int i = 0; i < N;i++){scanf("%d",&a[i]);}submax[0] = a[0];max = a[0];for(int i = 1; i < N; i++){if(submax[i-1] > 0){submax[i] = submax[i-1] + a[i];}else{submax[i] = a[i];}if (submax[i] > max){max = submax[i];}}printf("%d",max);return 0;}

   

            


0 0
原创粉丝点击