POJ 2479 Maximum sum
来源:互联网 发布:关于淘宝美工工作流程 编辑:程序博客网 时间:2024/06/13 08:13
- 总Time Limit:
- 1000ms
- Memory Limit:
- 65536kB
- Description
- Given a set of n integers: A={a1, a2,..., an}, we define afunction d(A) as below:
t1 t2
d(A) = max{ ∑ai + ∑aj | 1 <= s1 <= t1 < s2 <= t2 <= n }
i=s1 j=s2
Your task is to calculate d(A). - Input
- The input consists of T(<=30) test cases. The number of testcases (T) is given in the first line of the input.
Each test case contains two lines. The first line is an integern(2<=n<=50000). The second line contains n integers: a1, a2,..., an. (|ai| <= 10000).There is an empty line after eachcase. - Output
- Print exactly one line for each test case. The line shouldcontain the integer d(A).
- Sample Input
1
10
1 -1 2 2 3 -3 4 -4 5 -5
- Sample Output
13
- Hint
- In the sample, we choose {2,2,3,-3,4} and {5}, then we can getthe answer.
Huge input,scanf is recommended - 思路:定义两个数组:left[100000]和right[100000];分别存从左往右,和从右往左的子串的最大值;即:a[0],a[1], a[2],.....a[n],
left[i]表示:在 0 到 n之间的最大和子串的值;right[i]表示:i到n 之间的最大和子串的值。 -
求left[i]的方法与求right[i]的方法类似,这里给求left[i]的方法。采用dp思想:先知道left[0]= a[0] ,定义一个current =a[0],根据current求出a[1]时curent的值,即current在更换值;而current代表以i为一个终点,它(包含它)之前的最大和子串。if(current <0), 那么current = a[i];else current +=a[i]。再判断left[i-1]与current的大小,如果前者小,则,left[i] = current;否则,left =left[i-1]; -
计算 完left和rihgt后,再得到answer 为left[i]+right[i+1]里中最大的一个。 - 以题目给的数据举例:
-
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8]a[9]; -
1 -1 2 2 3 -3 4 -4 5 -5 - current(left)
1 0 2 4 7 4 8 4 9 4 - left[i]
1 1 2 4 7 7 8 8 9 9 - currebt(right)
9 8 9 7 5 2 5 1 5 -5 - right[i]
9 9 9 7 5 5 5 5 5 -5 - C语言:
ac代码 #include
inta[100000];
intleft[100000] = {0}; //从左往右时,以这个点为终点,在它前面的子串里面的和最大值;
intright[100000] = {0}; //从右往左时,以这个点为终点,在它前面的子串里面的和最大值;
intmain()
{
int T, n, i;
int current;
int answer;
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
for (i=0; i
{
scanf("%d", &a[i]);
}
//计算左边的子串最大值;
current = left[0] = a[0];
for(i=1; i
{
left[i] = left[i-1];
if(current < 0)
current = a[i];
else
current = current + a[i];
if(current > left[i-1])
left[i] = current;
}
//计算右边的子串的最大值;
current = right[n-1] = a[n-1];
for(i=n-2; i>=0; i--)
{
right[i] = right[i+1];
if(current < 0)
current = a[i];
else
current = current + a[i];
if(current > right[i+1])