您的位置:首页 > 其它

湘潭OJ 1264 挺好的一道贪心题

2017-05-25 21:33 786 查看
题目链接

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 mostm
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;
}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: