【子串和 44 动态规划】

来源:互联网 发布:矩阵逆matlab 编辑:程序博客网 时间:2024/06/02 23:06

子串和

时间限制:5000 ms  |  内存限制:65535 KB
难度:3
描述
给定一整型数列{a1,a2...,an},找出连续非空子串{ax,ax+1,...,ay},使得该子序列的和最大,其中,1<=x<=y<=n。
输入
第一行是一个整数N(N<=10)表示测试数据的组数)
每组测试数据的第一行是一个整数n表示序列中共有n个整数,随后的一行里有n个整数I(-100=<I<=100),表示数列中的所有元素。(0<n<=1000000)
输出
对于每组测试数据输出和最大的连续子串的和。
样例输入
151 2 -1 3 -2
样例输出
5
提示
输入数据很多,推荐使用scanf进行输入

第一次AC超时:

#include<iostream>#include<cstdio>using namespace std;#define N -100000int arr[1000000];int main(){    int n;    scanf("%d",&n);    while(n--){        int m;        int max=N;        scanf("%d",&m);        for(int i=0;i<m;i++)            scanf("%d",&arr[i]);        for(int i=0;i<m;i++){                int ans=0;            for(int j=i;j<m;j++){            ans+=arr[j];            if(ans>max){                max=ans;            }            }        }        printf("%d\n",max);    }}

第二次:

关键:if(sum<0) sum=0;

#include<cstdio>#include<iostream>using namespace std;int main(){    int t,k,n,i,max,sum;    scanf("%d",&t);    while(t--){        sum=0;        max=-1000000;        scanf("%d",&n);        for(i=0;i<n;i++){            scanf("%d",&k);            sum+=k;            if(sum>max)                max=sum;            if(sum<0)                sum=0;        }        printf("%d\n",max);    }}

第三次:动态规划。

#include<iostream>#include<cstdio>using namespace std;#define max(a,b) a>b?a:bint a[1000005],dp[1000005];int MAX(int n){    dp[1]=a[1];    int Max=dp[1];    for(int i=2;i<=n;i++){        dp[i]=max(dp[i-1]+a[i],a[i]);        Max=max(dp[i],Max);    }    return Max;}int main(){    int T;    cin>>T;    while(T--){        int n;        cin>>n;        for(int i=1;i<=n;i++)            cin>>a[i];        cout<<MAX(n)<<endl;    }}

总结:

求最大一个子序列,当前边的序列加上下一个元素,如果没有下一个元素大,则把最大的和等于下一个元素。

如果前边的序列和小于0,则应该把和归0.然后继续判断剩余的子序列。

可以总结为动态规划。

原创粉丝点击