连续两个不相交子串和
Maximum sum
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
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.
题意 :
给定一个序列求出该序列两个不相交子串的最大和
思路 :
两个数组,DP[i][0],DP[i][1];
DP[i][0]表示的是从0~i中连续子串的最大和
DP[i][1]表示i~n-1中连续子串的最大和
则题目就变成求max{DP[i][0]+DP[i+1][1]}
和一个序列子串和最大有区别,我们需要一直维持最大值,然后在一个循环里解决
超时代码
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 5e4 + 5;
typedef long long ll;
ll a[maxn];
ll dp[maxn][2];
int main(){
int t;cin >> t;
while(t --){
int n;cin >> n;
for(int i = 0;i < n;i ++){
cin >> a[i];
if( i )
dp[i][0] = max(dp[i - 1][0] + a[i],a[i]);
else
dp[i][0] = a[i];
}
for(int i = n - 1;i >= 1;i --){
if( i != n - 1)
dp[i][1] = max(dp[i + 1][1] + a[i],a[i]);
else
dp[i][1] = a[i];
}
ll ans = -1e18;
for(int j = 0;j < n - 1;j ++)
for(int i = j + 1;i < n ;i ++){
ans = max(ans,dp[j][0] + dp[i][1]);
}
cout << ans << endl;
}
return 0;
}
AC代码
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 5e4 + 5;
int a[maxn];
int dp[maxn][2];
int main(){
int t;scanf("%d",&t);;
while(t --){
int n;scanf("%d",&n);
int sum = 0;
for(int i = 0;i < n;i ++){
scanf ("%d", &a[i]) ;
if( i ){
sum = max(sum + a[i], a[i]);
dp[i][0]=max(sum,dp[i-1][0]);
}
else
dp[i][0] = sum = a[i];
}
for(int i = n - 1;i >= 0 ;i --){
if( i != n - 1){
sum = max(sum + a[i], a[i]);
dp[i][1]=max(sum,dp[i+1][1]);
}
else
dp[i][1] = sum = a[i];
}
int ans = -(1<<30);
for(int i = 0;i < n - 1;i ++){
ans = max(ans,dp[i][0] + dp[i + 1][1]);
}
printf("%d\n",ans);
}
return 0;
}
本文探讨如何高效地计算给定整数序列中两个不相交子串的最大和,通过介绍动态规划方法,对比超时和优化后的代码实现,以及关键步骤的解释。适合理解子串和问题及动态规划在求解此类问题中的应用。
992

被折叠的 条评论
为什么被折叠?



