牛客月赛114
D. 神孙权
td 数组存的是前 i 轮一共弃置掉的手牌数,dc 数组是前 i 轮结束后还剩多少手牌。
先二分出最多进行局数,也就是最多摸几张牌。对于枚举的摸牌次数,头和尾各摸几张不确定,对于这种有两个变量要枚举的情况,方法是只去枚举一个,另一个用枚举的变量表示出来。
假设现在要摸 k 张牌,枚举从头摸 i 张,那从尾就是摸 k - i 张,当然也可以小于 k - i 张,并不是一定要摸满 k 张。此时只需要维护一个后缀最大值就能快速查询。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 5, INF = 1e18;int T, n, k, ans, td[N], dc[N], a[2], b[N], dl[N], dr[N], mxr[N];
string s;signed main()
{cin >> n >> k;for (int i = 1; i <= n; i ++){cin >> a[i];b[i] = i - 1;td[i] = td[i - 1] + b[i];dc[i] = td[i] - i;}int num = lower_bound(dc + 1, dc + n + 1, k) - dc;num --;int cnt = min(num, n);for (int i = 1; i <= n; i ++)dl[i] = dl[i - 1] + a[i];for (int i = 1; i <= n; i ++){dr[i] = dr[i - 1] + a[n - i + 1];mxr[i] = max(dr[i], mxr[i - 1]);}for (int i = 0; i <= cnt; i ++)ans = max(ans, dl[i] + mxr[cnt - i]);cout << ans;return 0;
}