您的位置:首页 > 其它

Codeforces 846 C Four Segments(前缀和+枚举)

2017-09-07 12:42 369 查看
题目地址

题意:给你一个序列,定义一种运算sum(a,b)=num[a]+…+num[b-1],注意sum(a,a)=0。让你求出最大的res=sum(0, delim0) - sum(delim0, delim1) + sum(delim1, delim2) - sum(delim2, n) 时的delim0,delim1,delim2。

思路:用前缀和去节省每一次求区间和的时间,因为当a,b相同时sum操作是为0的,所以最不理想的时候res中减操作的时候就为0。所以我们就可以去枚举delim0以及delim2,那delim1的话就是在过程中求出一个区间和为最下的非正数的范围就好了。然后每次记录与之前进行比较,取最大值得时候的delim0,delim1,delim2。

#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <iomanip>
#define N 5010
#define M 555005
#define LL __int64
#define inf 0x3f3f3f3f3f3f3f3f
#define lson l,mid,ans<<1
#define rson mid+1,r,ans<<1|1
#define getMid (l+r)>>1
#define movel ans<<1
#define mover ans<<1|1
using<
4000
/span> namespace std;
const LL mod = 1000000007;
LL num
, sum
;
long long solve(int l, int r) {
return sum[r - 1] - sum[l - 1];
}
int main() {
cin.sync_with_stdio(false);
int n;
int a, b, c;
while (cin >> n) {
sum[0] = 0;
for (int i = 1; i <= n; i++) {
cin >> num[i];
sum[i] = sum[i - 1] + num[i];
}
LL ans = -inf;
for (int i = 0; i <= n; i++) {
LL k = sum[i];
int pos = i;
for (int j = i; j <= n; j++) {
if (sum[j] < k) {
pos = j;
k = sum[j];
}
LL cnt = solve(1, i + 1) - solve(i + 1, pos + 1) + solve(pos + 1, j + 1) - solve(j + 1, n + 1);
if (cnt >= ans) {
a = i; b = pos; c = j;
ans = cnt;
}
}
}
cout << a << " " << b << " " << c << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: