Description
Given a set of n integers: A={a1, a2,..., an}, we define a function d(A) as below: 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
1101 -1 2 2 3 -3 4 -4 5 -5
Sample Output
13
分析:
动态规划。枚举两个子串的分割点i,1<=i<=n,分别求两个串的最大子串,求出的最大值即为所求。设dp[i]为以元素i结束的子串的最大值,则dp[i]=max{dp[i-1]+a[i],a[i]}。设lt[i]为串a[1]-a[i]的最大子串的值,
则lt[i]=max{lt[i-1],dp[i]},同理可求rt[i]。code:
View Code
#include#define max(A,B)((A)>=(B)?(A):(B)) const int INF=100005; int a[INF]; int lt[INF]; int rt[INF]; int dp[INF]; int main() { int i,j,c,n,sum; scanf("%d",&c); while(c--) { scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&a[i]); dp[n+1]=dp[0]=-INF; lt[0]=rt[n+1]=-INF; //正向求。从左向右求dp[i]、lt[i] for(i=1;i<=n;i++) dp[i]=max(dp[i-1]+a[i],a[i]); for(i=1;i<=n;i++) lt[i]=max(dp[i],lt[i-1]); //逆向求。从右向左求dp[i]、rt[i] for(i=n;i>=1;i--) dp[i]=max(dp[i+1]+a[i],a[i]); for(i=n;i>=1;i--) rt[i]=max(dp[i],rt[i+1]); //枚举两个子串的分隔点i sum=-INF; for(i=1;i<=n;i++) sum=max(sum,lt[i]+rt[i+1]); printf("%d\n",sum); } return 0; }