Partial Sum
Accepted : 98 Submit : 391
Time Limit : 3000 MS Memory Limit : 65536 KB
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
Source
XTU OnlineJudge
sum[i]=∑ii=1a[i]
sum[0]=0
|∑rj=l+1a[j]|−C=|sum[r]−sum[l]|−C
显然res=|sum[r]−sum[l]|−C,sum[r]越大,sum[l]越小,res越大
对sum[0..n]进行排序,依次选择sum[n]−sum[0],sum[n−1]−sum[1],...sum[n−i]−sum[i],直到abs值小于C即可
#include<stdio.h>
#include <iostream>
#include<stdlib.h>
#include<algorithm>
#include<vector>
#include<deque>
#include<map>
#include<set>
#include<queue>
#include<math.h>
#include<string.h>
#include<string>
using namespace std;
#define ll long long
#define pii pair<int,int>
const int inf = 1e9 + 7;
const int N = 1e5+5;
int sum[N];
int main()
{
//freopen("/home/lu/Documents/r.txt","r",stdin);
//freopen("/home/lu/Documents/w.txt","w",stdout);
int n,m,c;
while(~scanf("%d%d%d",&n,&m,&c)){
for(int i=1;i<=n;++i){
scanf("%d",&sum[i]);
sum[i]+=sum[i-1];
}
sort(sum,sum+n+1);
ll ans=0;
for(int i=0;i<m;++i){
if(abs(sum[n-i]-sum[i])>c){
ans+=abs(sum[n-i]-sum[i])-c;
}
else{
break;
}
}
printf("%I64d\n",ans);
}
return 0;
}
本文介绍了一种解决特定数学问题的方法:给定整数序列,通过最多m次操作选取两个下标形成子序列,计算子序列绝对和减去常数C后的最大累积差值。文章提供了完整的算法思路和C++实现代码。
547

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



