题意:n个数,我们选择不重合的m组连续子序列,问最大和是多少
思路:第j个数,是在第包含在第i组里面,还是自己独立成组。方程 dp[i][j]=Max(dp[i][j-1]+a[j] , max( dp[i-1][k] ) + a[j] ) 0<k<j空间复杂度,m未知,n<=1000000, 继续滚动数组。
空间复杂度 n^3. n<=1000000. 显然会超时,继续优化。max( dp[i-1][k] ) 就是上一组 0....j-1 的最大值。我们可以在每次计算dp[i][j]的时候记录下前j个的最大值 用数组保存下来 下次计算的时候可以用,这样 时间复杂度为 n^2.
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define INF 0x7fffffff 4 const int N=1e6+10; 5 6 int dp[N]; 7 int a[N]; 8 int mmax[N]; 9 10 int main(){ 11 int n,m; 12 while(scanf("%d%d",&m,&n)!=EOF){ 13 int Max; 14 for(int i=1;i<=n;i++){ 15 scanf("%d",&a[i]); 16 mmax[i]=0; 17 dp[i]=0; 18 } 19 dp[0]=0; 20 mmax[0]=0; 21 for(int i=1;i<=m;i++){ 22 Max=-INF; 23 for(int j=i;j<=n;j++){ 24 dp[j]=max(dp[j-1]+a[j],mmax[j-1]+a[j]); 25 mmax[j-1]=Max; 26 Max=max(Max,dp[j]); 27 } 28 //for(int i=1;i<=n;i++) cout<<dp[i]<<" ";cout<<endl; 29 // for(int i=1;i<=n;i++) cout<<mmax[i]<<" ";cout<<endl; 30 } 31 printf("%d ",Max); 32 } 33 return 0; 34 }