专栏文章
题解:CF2085D Serval and Kaitenzushi Buffet
CF2085D题解参与者 2已保存评论 1
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mipq2diw
- 此快照首次捕获于
- 2025/12/03 16:05 3 个月前
- 此快照最后确认于
- 2025/12/03 16:05 3 个月前
Part1:思路
这题虽然简单,但是反应的思维方式比较有意义。
首先,去刻画什么情况下一盘寿司能被选择——显然是后面至少有 分钟空着没事做。
这里的关键在于后面,但是后面的情况如何正着做是不知道的。换句话说,前面数的选择与否只与后面的情况有关,所以我们从后往前考虑。
遇到这种选择物品题,我们往往第一反应都会是贪心。从后往前扫的时候,假若现在是第 分钟,那么后面恰好有 分钟空余,我们将选择当前这盘寿司。
但是这里显然不满足最优子结构。考虑刻画非最优的情况。具体的,对于第 中任意一盘没选中的寿司,假若选择它会带来更大美味值,那么我们都可以使用后面的寿司替换第 盘。
更加广泛的,对于任意 ,我们都可以使用第 盘寿司替换第 盘。这时候就得到了一个反悔贪心,对于其正确性此时再稍作归纳便可得知。
Part2:代码
CPP#include <bits/stdc++.h>
#define FL(i, a, b) for (int i = (a); i <= (b); ++i)
#define FR(i, a, b) for (int i = (a); i >= (b); --i)
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define Sz(v) ((int)(v).size())
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
constexpr int N = 2e5 + 10;
int n, k, d[N];
multiset<int> s1;
void Solve() {
scanf("%d %d", &n, &k);
FL(i, 1, n) {
scanf("%d", &d[i]);
}
s1.clear();
ll ans = 0;
FR(i, n, 1) {
int lim = (n - i + 1) / (k + 1);
if (Sz(s1) < lim) {
ans += d[i];
s1.emplace(d[i]);
} else {
if (!s1.empty() && *s1.begin() < d[i]) {
ans -= *s1.begin();
s1.erase(s1.begin());
ans += d[i];
s1.emplace(d[i]);
}
}
}
printf("%lld\n", ans);
}
int main() {
int T = 1;
scanf("%d", &T);
for (; T--; Solve());
return 0;
}
相关推荐
评论
共 1 条评论,欢迎与作者交流。
正在加载评论...