1 条题解
-
1
用f[i]表示前i个人可以得到的最大效率值。那么可以枚举前i个人里面最后一个休息的人,设这个人是x,那么f[i]就等于第x+1到第i个人的效率值之和,加上f[x-1]。其中第一部分可以用前缀和来优化,设sum[i]表示从i到n的效率值之和,则第一部分可以表示为sum[x+1]-sum[i+1]。
题目限定不能有连续的超过k个工人,相当于在i-k到i里面,选出使得f[x]+sum[x+1]-sum[i+1]最大的x,即滑动窗口求最值,可以用单调队列优化。
需要注意,由于求最值的范围包括了i本身,因此循环到i时,需要先把i加入队列,再求最值。
核心代码
long long calc(int x) { return f[x - 1] + sum[x + 1]; } int main() { cin >> n >> k; for (int i = 1; i <= n; i++) cin >> e[i]; for (int i = n; i >= 1; i--) sum[i] = e[i] + sum[i + 1]; q.push_back(0); for (int i = 1; i <= n; i++) { while (!q.empty() && i - q.front() > k) q.pop_front(); while (!q.empty() && calc(q.back()) <= calc(i)) q.pop_back(); q.push_back(i); f[i] = f[max(q.front() - 1, 0)] + sum[q.front() + 1] - sum[i + 1]; } cout << f[n]; return 0; }
- 1
信息
- ID
- 747
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- (无)
- 递交数
- 53
- 已通过
- 21
- 上传者