小奇挖矿2
小奇挖矿2 - 题解
题目大意
现在有 个星球,从左到右标号为 到 ,小奇最初在 号星球。
有 处矿体,第 处矿体有 单位原矿,在第 个星球上。
由于飞船使用的是老式的跳跃引擎,每次它只能从第 号星球移动到第 号星球或 号星球。每到一个星球,小奇会采走该星球上所有的原矿,求小奇能采到的最大原矿数量。
注意,小奇不必最终到达 号星球。
大概思路
Part 1 (20 pts)
既然第一个条件给了 ,所以只需要判断这个点会不会被走到就行了。
判断函数:
bool check(int n) {
for (int i = 1; i * 7 <= n; i ++) {
if ((n - i * 7) % 4 == 0) {
return 1;
}
} return 0;
}
Part 2 (40 pts)
详情
说实话,我真的不会。跳过(慌Part 3 (60 pts)
我一看,。这不就是妥妥的 嘛。
代码:
#include <bits/stdc++.h>
#define Maxn 100005
using namespace std;
int n, m, a[Maxn], b[Maxn], dp[Maxn], maxl;
bool check(int x) {
for (int i = 0; i <= x / 7; i ++) {
if ((x - i * 7) % 4 == 0) {
return 1;
}
} return 0;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i ++) {
cin >> a[i] >> b[i];
if (check(b[i])) { // 切勿漏掉
dp[b[i]] += a[i];
}
}
for (int i = 0; i <= m; i ++) {
int now = dp[i];
if (i >= 4) {
dp[i] = max(dp[i], now + dp[i - 4]);
} if (i >= 7) {
dp[i] = max(dp[i], now + dp[i - 7]);
} maxl = max(maxl, dp[i]);
} // 纯纯dp
cout << maxl;
return 0;
}
Part 4 (70 pts)
枚举后可以知道,点 不能走到的点 有 。
所以我们得到了一个更快的 函数,而且不仅仅适用于起点为 了。
新版 函数:
bool check(int x, int y) {
if (x == y + 1 || x == y + 2 || x == y + 3 ||
x == y + 5 || x == y + 6 || x == y + 9 ||
x == y + 10 || x == y + 13 || x == y + 17) {
return 0;
} return 1;
} // 判断y那能否走到x
容易得到:
根据新的递推式可以得到代码:
#include <bits/stdc++.h>
#define Maxn 100005
using namespace std;
int n, m, tot = 0, dp[Maxn], maxl;
struct Point {
int x, num;
} a[Maxn], p[Maxn];
bool check(int x, int y) {
if (x == y + 1 || x == y + 2 || x == y + 3 ||
x == y + 5 || x == y + 6 || x == y + 9 ||
x == y + 10 || x == y + 13 || x == y + 17) {
return 0;
} return 1;
}
bool cmp(Point a, Point b) {
return a.x <= b.x;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i ++) {
cin >> a[i].num >> a[i].x;
} sort(a + 1, a + n + 1, cmp);
for (int i = 1; i <= n; i ++) {
if (check(a[i].x, 0)) {
if (a[i].x == p[tot].x) {
p[tot].num += a[i].num;
} else {
tot ++, p[tot] = a[i];
}
}
}
// for (int i = 1; i <= tot; i ++) {
// cout << p[i].x << " " << p[i].num << "\n";
// }
for (int i = 1; i <= tot; i ++) {
dp[i] = p[i].num;
for (int j = 1; j < i; j ++) {
if (check(p[i].x, p[j].x)) {
// cout << i << " " << j << " : " << dp[i] << " " << dp[j] << " " << p[i].num << " ";
dp[i] = max(dp[i], dp[j] + p[i].num);
// cout << dp[i] << "\n";
}
} maxl = max(maxl, dp[i]);
}
cout << maxl;
return 0;
}
吐槽:将近一倍的脑细胞消耗量多换来了 (不值。这边认为考试的时候可以把 拿到就很可以了。
Part 5 (100 pts)
终于迎来了正解。
我们发现, 的时间复杂度为 。所以只有 。
观察递推式,发现有一项是不变的,所以有如下推导:
可以联想到单调队列优化DP和优先队列优化DP。我这里写的是优先队列优化DP。
#include <bits/stdc++.h>
#define Maxn 100005
using namespace std;
int n, m, tot = 0, dp, maxl;
struct Point {
int x, num;
bool operator <(const Point a) const{
return num < a.num;
}
} a[Maxn], p[Maxn], tmp[Maxn], t;
int del = 0;
priority_queue<Point> q;
bool check(int x, int y) {
if (x == y + 1 || x == y + 2 || x == y + 3 ||
x == y + 5 || x == y + 6 || x == y + 9 ||
x == y + 10 || x == y + 13 || x == y + 17) {
return 0;
} return 1;
}
bool cmp(Point a, Point b) {
return a.x <= b.x;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i ++) {
cin >> a[i].num >> a[i].x;
} sort(a + 1, a + n + 1, cmp);
for (int i = 1; i <= n; i ++) {
if (check(a[i].x, 0)) {
if (a[i].x == p[tot].x) {
p[tot].num += a[i].num;
} else {
tot ++, p[tot] = a[i];
}
}
}
// for (int i = 1; i <= tot; i ++) {
// cout << p[i].x << " " << p[i].num << "\n";
// }
tmp[0].num = tmp[0].x = 0;
q.push(tmp[0]);
for (int i = 1; i <= tot; i ++) {
dp = del = 0;
while (!q.empty()) {
t = q.top(), q.pop();
tmp[++ del] = t;
if (check(p[i].x, t.x)) {
dp = t.num + p[i].num;
break;
}
}
for (int j = 1; j <= del; j ++) {
q.push(tmp[j]);
} // 补充点的信息
tmp[0].num = dp, tmp[0].x = p[i].x;
q.push(tmp[0]); // 新增点的信息
}
cout << q.top().num;
return 0;
}
吐槽:谁家良心考试第一题这么变态。
此篇结。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)