NYOJ44

来源:互联网 发布:随身wifi无限流量 知乎 编辑:程序博客网 时间:2024/05/17 01:23


子串和

时间限制: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
#include<stdio.h>  int main()  {      int i,j,n,m,sum,maxsum;      scanf("%d",&n);      while(n--)      {          scanf("%d%d",&m,&j);          sum = maxsum = j;          for(i=1;i<m;i++)          {              scanf("%d",&j);              if(sum < 0)//如果和小于0,从当前值开始从新求和                 sum = j;              else                 sum += j;              if(maxsum < sum) maxsum = sum;//更新最大值          }          printf("%d\n",maxsum);      }      return 0;  }  

dp[i] 表示以第i个元素结尾的子串的最大和的值

那么dp[i]的来源可能是dp[i-1]+x[i](i项一直累加),或者x[i](可能前前i-1项和还没有第i项大)

然后 状态转移就是 dp[i]=max(dp[i-1]+x[i],x[i])

#include<cstdio>  #include<cstring>  #include<algorithm>  using namespace std;  const int maxn=1000005;  int x[maxn],dp[maxn];  int maxsum(int n)  {      memset(dp,0,sizeof(dp));      int ans=dp[0]=x[0];      for(int i=1;i<n;++i)      {          dp[i]=max(dp[i-1]+x[i],x[i]);          ans=max(ans,dp[i]);      }      return ans;  }  int main()  {      int t;      scanf("%d",&t);      while(t--)      {          int n;          scanf("%d",&n);          for(int i=0;i<n;++i)          {              scanf("%d",&x[i]);          }          printf("%d\n",maxsum(n));      }      return 0;  }  


参考博客:http://blog.csdn.net/sd6264456/article/details/8671825