https://www.nowcoder.com/acm/contest/134/H
题解:
利用滑动窗口的想法,从左到右扫描,优先吃掉右边的。
从右边开始吃是因为右边影响的区域最多,如果从右边开始吃的话一定比从左边开始吃的操作要少
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vii;
typedef vector<ll> vll;
const int MAXN = 1e6 + 10;
const ll INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
const double eps = 1e-8;
int n, m, k;
vll p;
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
cout << setprecision(10) << fixed;
cin >> n >> m >> k;
p.resize(n + 1);
for(int i = 1; i <= n; i++)
cin >> p[i];
ll cur = 0, res = 0;
for(int i = 1; i <= min(n, m - 1); i++)//比较m-1的原因是因为从m到n为窗口
cur += p[i];
for(int i = min(n, m); i <= n; i++){//滑动窗口
cur += p[i];
for(int j = i; cur > k; j--){//窗口大于k开始吃糖果,右侧优先,直到小于k为止
ll cal = min(cur - k, p[j]);
res += cal;
p[j] -= cal;
cur -= cal;
}
cur -= p[i - m + 1];//滑动到下一个窗口
}
cout << res << endl;
cerr << "execute time : " << (double)clock() / CLOCKS_PER_SEC << endl;
return 0;
}