题意: 有一列共 n 个城市, 每个城市有美丽值b[i], 要访问一个子序列的城市, 这个子序列相邻项的原项数之差等于美丽值之差, 求最大的美丽值总和.
思路: 对于一个合法的子序列, b[i] - i 结果是一个定值, 统计该值取最大.
view code
#include <bits/stdc++.h> using namespace std; #define ll long long #define inc(i, l, r) for (int i = l; i <= r; i++) const int maxn = 1e6 + 5; int n, b[maxn]; int main() { cin >> n; map<int, ll> a; inc(i, 0, n - 1) { cin >> b[i]; a[b[i] - i] += b[i]; } ll res = 0; for (auto ite : a) res = max(res, ite.second); cout << res << "\n"; }
题意: 给出一个有向图和一个人的行动路径, 这个人每次移动前导航仪会给出从当前点到终点的一条最短路线, 如果这个人移动的路线与之不符, 导航仪会重新生成从下一个点出发到终点的最短路线. 问导航仪生成新路线的最小和最大次数.
思路: bfs求出所有点到终点的最短距离. 如果这个人移动时距离终点不是-1, 那他这次移动一定不在最短路线上; 否则, 检查是否有其他使距离-1的路线, 如果有, 那么就知道导航仪可能会重新生成路线.
view code
#include <bits/stdc++.h> using namespace std; #define ll long long #define inc(i, l, r) for (int i = l; i <= r; i++) const int maxn = 1e6 + 5; const int inf = 0x3f3f3f3f; vector<int> g[maxn]; vector<int> rg[maxn]; int a[maxn], d[maxn], vis[maxn]; int n, m, u, v, k; int main() { memset(d, 63, sizeof(d)); cin >> n >> m; inc(i, 1, m) { cin >> u >> v; rg[u].push_back(v); g[v].push_back(u); } cin >> k; inc(i, 1, k) cin >> a[i]; queue<int> que; que.push(a[k]); d[a[k]] = 0; vis[a[k]] = 1; while (que.size()) { int p = que.front(); que.pop(); inc(i, 0, (int)g[p].size() - 1) { if (!vis[g[p][i]]) { d[g[p][i]] = d[p] + 1; que.push(g[p][i]); vis[g[p][i]] = 1; } } } int res1 = 0, res2 = 0; for (int i = 1; i < k; i++) { int now = a[i], nxt = a[i + 1]; if (d[now] != d[nxt] + 1) res1++, res2++; else inc(j, 0, (int)rg[now].size() - 1) { if (d[rg[now][j]] + 1 == d[now] && rg[now][j] != nxt) { res2++; break; } } } cout << res1 << " " << res2; }
C - World of Darkraft: Battle for Azathoth
题意: 给出 n 个武器, m 个防具, 分别有攻击力 ai 和防御力 bi, 购买该装备需要的金币ci, 还有 p 个怪兽, 分别具有防御力xi, 攻击力yi, 打败它获得的金币ci. 现要求从中武器和防具中各选出恰好一个, 然后就可以打败 ai > xi 且 bi > yi 低的怪兽. 求最大获利.
思路: 没过, 写一下理论做法, 之后会回来验证. 对所有怪兽排序(不妨以 xi 作为第一关键字), 然后维护关于 yi 的线段树, 表示防御力为 i 时的最大获利, 而攻击力为当前怪兽xi + 1, 这样可以确保扫描过的怪兽 ai > xj, 而 bi > yj只是个区间查询的问题.
view code
NULL
心得: 我这一场就是在玩蛇, 乱交题, 各种bug. 开场A, 假了个枚举每个数作为子序列起点, 再并查集去掉已用的点的做法, 看到TLE的时候脑子才想到正解, 13min累计 2 发过. B题 35min 交的第一发, 但直到 73min 累计交 4 次才过, 中间出现的问题: 从终点出发bfs的图和沿人走的路径的图以为是一个图, 拿 i 当 d[i], 还有统计是否有其它使距离-1的边时没有break重复统计. C题没过, 剩 7min 发现写的是错的, 本来是按每个怪兽为节点查询BIT, 但是最优解并不一定对应打败一个怪兽, 可能是攻击力满足个a怪兽, 防御力却是满足另一个b怪兽. 感觉教训就是, 这场打的有点迷之自信, 想得不全面而不自知.