Max Sum Plus Plus

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 13462    Accepted Submission(s): 4425

 

 

Problem Description

Now I think you have got an AC inIgnatius.L's "Max Sum" problem. To be a brave ACMer, we alwayschallenge ourselves to more difficult problems. Now you are faced with a moredifficult problem.

 

Given a consecutive number sequence S1, S2,S3, S4 ... Sx, ... Sn (1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ Sx ≤ 32767). We define a function sum(i, j) = Si + ... + Sj (1 ≤ i ≤ j ≤ n).

 

Now given an integer m (m > 0), yourtask is to find m pairs of i and j which make sum(i1, j1) + sum(i2, j2) +sum(i3, j3) + ... + sum(im, jm) maximal (ix ≤ iy ≤ jx or ix ≤ jy ≤ jx is not allowed).

 

But I`m lazy, I don't want to write aspecial-judge module, so you don't have to output m pairs of i and j, justoutput the maximal summation of sum(ix, jx)(1 ≤ x ≤ m) instead.^_^

 

 

Input

Each test case will begin with two integersm and n, followed by n integers S1, S2, S3 ... Sn.

Process to the end of file.

 

 

Output

Output the maximal summation describedabove in one line.

 

 

Sample Input

1 3 1 2 3

2 6 -1 4 -2 3 -2 3

 

 

Sample Output

6

8

解题代码:

//学习c++编程,STL queue,stack,sort函数

#include<stdio.h>

#include<algorithm>

using namespace std;

inta[1000000],b1[1000000]={0},b2[1000000]={0};//注意:一般全局的,静态的变量所允许分配的最大空间比局部的,动态的变量的要大。

int main()

{

       intm,n,i,j,p,q,max;

       while(scanf("%d%d",&m,&n)!=EOF)

       {

             

              for(i=1;i<=n;i++)

              {

                     scanf("%d",&a[i]);

                     b1[i]=b2[i]=0;

              }

              max=0;//对每个事例初始化max

              for(i=1;i<=m;i++)

              {

                     for(j=0;j<=n;j++)

                     {

                            if(j==0)b2[j]=0;

                            elseif(i<=j)

                            {

                                   p=max+a[j];//*max_element(b1+i-1,b1+j)+a[j];也可以不用max改为这一种算法但是会超时,在计算的时候把相应max求出来

                                   q=b2[j-1]+a[j];//没有必要再一次重复的求max了,大大节约了时间

                                   b2[j]=p>q?p:q;

                                   max=max>b1[j]?max:b1[j];//赋值下一个b2[j]的max

                            }

                     }                  

                     for(j=0;j<=n;j++)b1[j]=b2[j];

                     max=b1[i];//赋值下一行的第一个(i==j时)b2[j]的max

              }

              printf("%d\n",*max_element(b2+m,b2+n+1));

       }

       return0;

}

1.这道题是最大字串的推广和深入,是继最长公共子序列之后的有一个用二维数组解决的经典的问题。

2.解题思路:设b(i,j)表示数组a的前j项中i个字段和的最大值,且第i个子段含a[j](1<=i<=m,i<=j<=n)。则所求最优值显然为。与最大子段和问题类似地,计算b(i,j),的递归式为:

其中表示第i个子段含a[j-1],而表示第i个子段仅含a[j]。初始时,b(0,j)=0,(1jn);b(i,0)=0,(1im)。

3.,活用数学方法证明,牢记递归式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值