9:Maximum sum

Description

Given a set of n integers: A={a1, a2,..., an}, we define a function d(A) as below:

d(A)=sum{a[s1]~a[t1]}+sum{a[s2]~a[t2]}

The rule is 1<=s1<=t1<s2<=t2<=n.

Your task is to calculate d(A).

Input

The input consists of T(<=30) test cases. The number of test cases (T) is given in the first line of the input.
Each test case contains two lines. The first line is an integer n(2<=n<=50000). The second line contains n integers: a1, a2, ..., an. (|ai| <= 10000).There is an empty line after each case.

Output

Print exactly one line for each test case. The line should contain 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 get the answer.

Huge input,scanf is recommended.


自己写的程序(其实又给弄麻烦了,算法这块自己确实不行):

package OJ;

import java.util.*;

public class P9_temp {

	public static void main(String[] args) {
		
		class Find {
			public int fromLtoR(List<Integer> al){
//				int sum = 0;
				int bigger = 0;
				if(al.size()%2 == 0){  //大小为偶数
					int i = 0;
					int temp = 0;
					while(i<al.size()){
						temp += (al.get(i) + al.get(i+1));
						if(temp > bigger)
							bigger = temp;
						i = i+2;
					}
				}
				else {   //大小为奇数
					int i = 0;
					int temp =0;
					if(al.size() > 1){
						while(i<al.size()-1){
							temp += (al.get(i) + al.get(i+1));
							if(temp > bigger)
								bigger = temp;
							i = i+2;
						}
					}
				}
				return bigger;
			}
			
			public int fromRtoL(List<Integer> al){
				int bigger = 0;
				if(al.size()%2 == 0){  //大小为偶数
					int i = al.size()-1;
					int temp = 0;
					while(i > -1){
						temp += (al.get(i) + al.get(i-1));
						if(temp > bigger)
							bigger = temp;
						i = i-2;
					}
				}
				else {   //大小为奇数
					int i = al.size()-1;
					int temp =0;
					if(al.size() > 1){
						while(i>0){
							temp += (al.get(i) + al.get(i-1));
							if(temp > bigger)
								bigger = temp;
							i = i-2;
						}
					}
				}
				return bigger;
			}
		}
		
		Scanner in = new Scanner(System.in);
		int cases = in.nextInt();
		for(int k=0; k<cases; k++){
			int times = in.nextInt();
			ArrayList<Integer> al = new ArrayList<Integer>();
			al.add(0);
			for(int i=0; i<times; i++){
				int temp = in.nextInt();
				int longth = al.size() - 1;
				if(al.get(longth) >= 0 && temp >= 0)
					al.set(longth, al.get(longth)+temp);
				else if(al.get(longth) <= 0 && temp <= 0)
					al.set(longth, al.get(longth)+temp);
				else 
					al.add(temp);
			}
			int big = 0;
			int bigL = 0;
			int bigger = 0;
			int biggerL = 0;
			for(int j=0; j<al.size(); j++){
				if(j == 0){
					big = al.get(j);
					bigger = al.get(j);
					bigL = j;
					biggerL = j;
				}
				else{
					if(al.get(j) >= bigger){
						bigger = al.get(j);
						biggerL = j;
					}
					else if(al.get(j) >= big){
						big = al.get(j);
						bigL = j;
					}
				}		
			}
			Find f = new Find();
			if(bigL > biggerL){//保证bigL < biggerL
				int temp = biggerL;
				biggerL = bigL;
				bigL = temp;
			}
			if(bigL != biggerL){ //有两个最大值
				int t1 = f.fromRtoL(al.subList(0, bigL));
				int t3 = f.fromLtoR(al.subList(bigL+1, biggerL));
				int t2 = f.fromRtoL(al.subList(bigL+1, biggerL));		
				int t4 = f.fromLtoR(al.subList(biggerL+1, al.size()));
				int result = t1+t2+t3+t4+big+bigger;
				System.out.println(result);
			}
			else {    //有一个最大值
				int t1 = f.fromRtoL(al.subList(0, bigL));
				int t2 = f.fromLtoR(al.subList(bigL+1, al.size()));
				int result = t1 + t2 + big;
				System.out.println(result);
			}
		}
		
	}

}



正确的算法:

在输入的同时,进行一次DP,计算出从左到右的最大值,并把它保存在数组dp的对应的下标元素中,这样之后,对于下标为i的元素,它其中保存的便是前面所 有元素可能的最大连续和。再从右到左进行一次DP,计算从右到左的最大连续和。假设此时已经算到下标为i的元素,那么将sum+dp[i-1]与ans进 行比较,将ans取较大者。最后当i到2的时候ans中的值即为所求的最大值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值