XTU 1264 Partial Sum 【思维 + 前缀和排序】

来源:互联网 发布:淘宝直通车怎么烧钱 编辑:程序博客网 时间:2024/06/04 18:15

传送门
//题意: 给定一个长度为n的序列和一个m, c, 每次选择两个端点l, r (0 <= l < r <= n) 然后得出 | sign i in (l+1,r)a[i] | - c 加到一个初始为0的计数器中, 最多选择m次, 且每个端点最多只能被选择一次. 问这个计数器最大可以是多大.
//思路: 凡是区间和问题都要联想到前缀和啊!!!! 区间问题都要想到前缀呀!!!
从题意中可以很好的看出我们就是要求一个区间和, 自然就想到了前缀和, 那么我们先求出序列的前缀和, 然后对前缀和排序, 然后每次用最大的前缀和 - 最小的前缀和再取绝对值即可. 注意就是要把0这个前缀算进去, 因为是选区间本身. 二是注意当中途某次算出的答案已经为负时就直接break掉, 因为这不会让答案更优.

AC Code

const int maxn = 1e5+5;int a[maxn],sum[maxn];void solve(){    int n,m,c;    while(~scanf("%d%d%d",&n,&m,&c)) {        Fill(sum,0);        for (int i = 1 ; i <= n ; i++) {            scanf("%d", &a[i]);            sum[i] = sum[i-1] + a[i];        }        sort(sum, sum+n+1);        ll ans = 0;        for (int i = 0 ; i <= n/2 && m; i++) {            ll tmp = abs(sum[n-i] - sum[i]) - c ;            if (tmp < 0 ) break;            ans += tmp;            m--;        }        cout << ans << endl;    }}
原创粉丝点击