不是???
2026-07-14 16:15:11
发布于:福建
我今天打开题目发现《158****5636》这个人acgo结束的挑战赛还用AI作弊,我看了之后有点无语!代码我丢下面了!!!
#include <iostream>
#include <vector>
#include <algorithm>
#include <deque>
using namespace std;
// 定义 long long 以避免溢出
typedef long long ll;
int main() {
// 优化 IO
ios::sync_with_stdio(false);
cin.tie(NULL);
int n, L, R;
ll C;
if (!(cin >> n >> L >> R >> C)) return 0;
vector<ll> a(n + 1);
vector<ll> S(n + 1, 0); // 前缀和 S[i] = a + ... + a[i]
for (int i = 1; i <= n; ++i) {
cin >> a[i];
S[i] = S[i - 1] + a[i];
}
// f[i] 表示前 i 个位置能获得的最大美观值
vector<ll> f(n + 1, 0);
// 单调队列,存储的是起始位置 j
// 我们需要维护 g[j] = f[j-2] - S[j-1] 的最大值
// 队列中的 j 对应的 g[j] 单调递减
deque<int> q;
for (int i = 1; i <= n; ++i) {
// 1. 尝试将新的起始位置 j_new 加入队列
// 以 i 结尾的灯带,最短长度 L,所以最早开始位置 j_new = i - L + 1
int j_new = i - L + 1;
if (j_new >= 1) {
// 计算 g[j_new] = f[j_new - 2] - S[j_new - 1]
// 注意处理 j_new - 2 < 0 的情况,此时 f 为 0
ll prev_f = (j_new - 2 >= 0) ? f[j_new - 2] : 0;
ll val = prev_f - S[j_new - 1];
// 维护单调递减队列:移除队尾比当前值小的元素
while (!q.empty()) {
int j_tail = q.back();
ll prev_f_tail = (j_tail - 2 >= 0) ? f[j_tail - 2] : 0;
ll val_tail = prev_f_tail - S[j_tail - 1];
if (val_tail <= val) {
q.pop_back();
} else {
break;
}
}
q.push_back(j_new);
}
// 2. 移除过期的起始位置
// 以 i 结尾的灯带,最长长度 R,所以最晚开始位置 j_min = i - R + 1
// 队列中的 j 必须 >= j_min
int j_min = i - R + 1;
while (!q.empty() && q.front() < j_min) {
q.pop_front();
}
// 3. 计算 f[i]
// 选项 1: 第 i 个位置不覆盖,f[i] = f[i-1]
f[i] = f[i - 1];
// 选项 2: 第 i 个位置是某条灯带的结尾
if (!q.empty()) {
int j_best = q.front();
ll prev_f_best = (j_best - 2 >= 0) ? f[j_best - 2] : 0;
ll g_best = prev_f_best - S[j_best - 1];
// 候选值 = S[i] - C + g[j_best]
ll candidate = S[i] - C + g_best;
if (candidate > f[i]) {
f[i] = candidate;
}
}
}
cout << f[n] << endl;
return 0;
}
全部评论 2
- 置顶
5286967给我出来!!!
昨天 来自 福建
0 不是,都结束了还用AI有必要吗???
昨天 来自 福建
0













有帮助,赞一个