您的位置:首页 > 其它

NYOJ 44 子串和

2014-04-06 19:52 253 查看
这道题木可以用递归来做

首先分析问题,把子串分成两部分,有三种情况,1、最大子串和在做部分;2、最大子串和在右部分;3、最大子串和位于中间,跨越左右两部分。

那么问题可以转换成 max( dfs(左),dfs(右),lmax + rmax )。

以后做递归的题目一定记得要用 c 来写,这样的毛病都犯多少次了,总是记不住。。。。。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<limits.h>
using namespace std;
int a[10000010];
int maxx(int a,int b,int c )
{
    a = a>b?a:b;
    a = a>c?a:c;
    return a;
}
int dfs(int a[],int left,int right)
{
    int i,m,lmax,rmax,sum;
    if(left == right) return a[left];
    m = (left + right)/2;
    lmax = sum = 0;
    for(i = m; i >= left; i--)
    {
        sum += a[i];
        lmax = lmax>sum?lmax:sum;
    }
    rmax = sum = 0;
    for(i = m+1; i <= right;i++)
    {
        sum += a[i];
        rmax = rmax>sum?rmax:sum;
    }
    return maxx(lmax+rmax,dfs(a,left,m),dfs(a,m+1,right));
}
int main()
{
    int N,n;
    scanf("%d",&N);
    //cin>>N;
    while(N--)
    {
        scanf("%d",&n);
        //cin>>n;
        memset(a,0,sizeof(a));
        //int maxx = -INT_MAX;
        for(int i = 0; i < n; i++)
            scanf("%d",&a[i]);
            //cin>>a[i];
        printf("%d\n",dfs(a,0,n-1));
        //cout<<dfs(a,0,n-1)<<endl;
    }
    return 0;
}


其实还有另外一种更为简单的方法,在接受子串的时候直接求最大和。

<span style="font-size:24px;">#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<limits.h>
#define maxn 1000000
int a[maxn+10];

int main()
{
     int t,n,i;
     scanf("%d",&t);
     while(t--)
     {
           int max = -INT_MAX;
           scanf("%d",&n);
           for(i=1;i<=n;++i)
           {
             scanf("%d",&a[i]);
             if(a[i-1]>0) a[i] += a[i-1];   //至 i 连续到此的最大和 
             if(a[i] > max) max = a[i];     //至 i 前总的最大值 
           }
           printf("%d\n",max); 
     }
     return 0;
}
</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: