经典算法问题 - 最大连续子数列和

暴力 O(n方)

#include 

//N是数组长度,num是待计算的数组,放在全局区是因为可以开很大的数组
int N, num[1024];

int main()
{
    //输入数据
    scanf("%d", &N);
    for(int i = 1; i <= N; i++)
        scanf("%d", &num[i]);
    
    int ans = num[1]; //ans保存最大子序列和,初始化为num[1]能保证最终结果正确
    //i和j分别是枚举的子序列的起点和终点,k所在循环计算每个子序列的和
    for(int i = 1; i <= N; i++) {
        for(int j = i; j <= N; j++) {
            int s = 0;
            for(int k = i; k <= j; k++) {
                s += num[k];
            }
            if(s > ans) ans = s;
        }
    }
    printf("%d\n", ans);

    return 0;
}

前缀和优化O(n*n)

#include 

//N是数组长度,num是待计算的数组,sum是数组前缀和,放在全局区是因为可以开很大的数组
int N, num[16384], sum[16384];

int main()
{
    //输入数据
    scanf("%d", &N);
    for(int i = 1; i <= N; i++)
        scanf("%d", &num[i]);
    
    //计算数组前缀和
    sum[0] = 0;
    for(int i = 1; i <= N; i++) {
        sum[i] = num[i] + sum[i - 1];
    }

    int ans = num[1]; //ans保存最大子序列和,初始化为num[1]能保证最终结果正确
    //i和j分别是枚举的子序列的起点和终点
    for(int i = 1; i <= N; i++) {
        for(int j = i; j <= N; j++) {
            int s = sum[j] - sum[i - 1];
            if(s > ans) ans = s;
        }
    }
    printf("%d\n", ans);

    return 0;
}

分治O(n*log(n))

#include
using namespace std;
#define ll long long
int a[16177216];
ll solve(int l,int r){
    if(l==r) return a[r];
    int m=l+r>>1;
    ll lans=solve(l,m);
    ll rans=solve(m+1,r);
    ll sum=0;
    ll lmax=a[m],rmax=a[m+1];
    for(int i=m;i>=l;i--)
    {
        sum+=a[i];
        if(sum>lmax) lmax=sum;
    }
    sum=0;
    for(int i=m+1;i<=r;i++){
        sum+=a[i];
        if(sum>rmax) rmax=sum;
    }
    ll ans=lmax+rmax;
    if(lans>ans) ans=lans;
    if(rans>ans) ans=rans;
    return ans;
} 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    while(cin>>n)
    {
        for(int i=1;i<=n;i++) cin>>a[i];
        cout<

DP O(n)

#include
using namespace std;
int a[14839487];
int main(){
    int n,i;
    while(cin>>n){
        a[0]=0;
        for(i=1;i<=n;i++)
        cin>>a[i];
        int ans=a[1];
        for(i=1;i<=n;i++)
        {
            if(a[i-1]>0) a[i]+=a[i-1];
            if(a[i]>ans) ans=a[i];
        }
        cout<

前缀和再优化 O(n)

#include
using namespace std;
int a[14839487];
int main(){
    int n,i;
    while(cin>>n){
        a[0]=0;
        for(i=1;i<=n;i++)
        cin>>a[i];
        int ans=a[1];
        int lmin=0;
        for(i=1;i<=n;i++)
        {
            a[i]+=a[i-1];
            if(a[i]-lmin>ans)
            ans=a[i]-lmin;
            if(a[i]

转载于:https://www.cnblogs.com/mch5201314/p/9481675.html

你可能感兴趣的:(经典算法问题 - 最大连续子数列和)