考查点:动态规划
思路:题目的意思实质是要从一个包含n个整数的集合中选取两个不相交的子集,在选取的所有方案中,找出两个子集和的最大值。为此,可以对输入数组进行两个方向的扫描。在正向扫描时,进行一次0(n)的dp,用dp1[i]表示前i个数中连续和的最大值,反相扫描类似。最后从k=0到k=n-2进行遍历,找出max(dp1[k]+dp2[k+1])。
提交情况:一开始是AC,但是由于使用new,内存使用太多,改掉了new,WA。原因是K的取值范围问题。
收获:使用new虽然内存使用更精确,但是由于存在多组测试数据,反而会使得内存使用率大幅上升,一定程度上影响时间。学习了如何在有负数的数组中,求最大连续和。
参考方案:http://fghtech.blogbus.com/logs/62555535.html
- #include <iostream>
- using namespace std;
- int a[50001],dp1[50001],dp2[50001];
- int main()
- {
- int test;
- scanf("%d",&test);
- while(test--)
- {
- int n;
- scanf("%d",&n);
- int sum=0,maxsum=-INT_MAX;
- for(int i=0;i<n;i++)
- {
- scanf("%d",&a[i]);
- sum+=a[i];
- if(sum>maxsum)
- {
- maxsum=sum;
- }
- dp1[i]=maxsum;
- if(sum<0)
- sum=0;
- }
- sum=0;
- maxsum=-INT_MAX;
- for(int i=n-1;i>=0;i--)
- {
- sum+=a[i];
- if(sum>maxsum)
- {
- maxsum=sum;
- }
- dp2[i]=maxsum;
- if(sum<0)
- sum=0;
- }
- int result=-INT_MAX;
- for(int i=0;i<n-1;i++)
- {
- if(dp1[i]+dp2[i+1]>result)
- result=dp1[i]+dp2[i+1];
- }
- cout<<result<<endl;
- }
- return 0;
- }