Partial Sum
Bobo has a integer sequence a1,a2,…,an of length n .Each time, he selects two ends 0≤l<r≤n and add |∑rj=l+1aj|−C into a counter which is zero initially.He repeats the selection for at most m times.
If each end can be selected at most once (either as left or right), find out the maximum sum Bobo may have.
Input
The input contains zero or more test cases and is terminated by end-of-file. For each test case:
The first line contains three integers n , m , C .The second line contains n integers a1,a2,…,an .
- 2≤n≤105
- 1≤2m≤n+1
- |ai|,C≤104
- The sum of n does not exceed 106 .
Output
For each test cases, output an integer which denotes the maximum.
Sample Input
4 1 1 -1 2 2 -1 4 2 1 -1 2 2 -1 4 2 2 -1 2 2 -1 4 2 10 -1 2 2 -1
Sample Output
3 4 2 0
选m个区间,让m个(区间和-c)的和最大。可以不选。(相当于选区间(l,r),l==r,什么都不会加)。
考虑贪心,,因为是区间和绝对值,所以可以求出所有前缀和,然后对前缀和排序,这时候只要从l=0,r=n。开始枚举区间就好了。
例如 7 8 9 -1 -2 -3 -4。选0-3,1-4,5-7;
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f;
ll sum[100010];
int main()
{
int n,m,c;
while(scanf("%d%d%d",&n,&m,&c)!=EOF)
{
sum[0]=0;
for(int i=1;i<=n;i++)
{
int x;scanf("%d",&x);
sum[i]=sum[i-1]+x;
}
sort(sum,sum+n+1);
int l=0,r=n;
ll ans=0;;
while(m--)
{
int v=sum[r]-sum[l];
if(v<=c)
break;
ans+=v-c;l++,r--;
}
printf("%I64d\n",ans);
}
return 0;
}