CF510D Fox And Jumping
题目
见链接。
题解
方法一
知识点:背包dp,STL。
题目意思是让我们判断能否从这些数中选出一些数使得选的数公共gcd为 ,如果可以输出最小花费。
一眼背包dp,但要map超大背包优化,因为数字很大 ,显然无法直接在第二维放下。
设 表示考虑到第 个数,所有数的gcd为 的情况。 因为用map优化了,没法填表了,因为每行都的元素都不确定,应该用刷表法,用这一行结果推到下一行。转移方程为:
前者表示不选第 个数的转移,后者表示选了第 个数的转移。
因为不能 memset
初始化正无穷,因此要做到循环中对第一次出现的状态初始化。同时,这也是解决数组太大每次全部初始化很费时间情况下的一种技巧。
注意为了方便,初始化了 。用于每次选一个数自己是第一个数的情况,能正确被标记而不用特判,即 。因为在我们写的gcd函数里, 可以当作特殊的单位元,特殊之处在于其应该出现在函数的后面一个位置,即 ,否则会出错。
时间复杂度 ,qwq最大公约数种类不知道怎么算
空间复杂度
方法二
知识点:BFS,优先队列,记忆化搜索。
说白了就是记忆化搜索,用广搜做最短路,求花费最小的路径,因此用优先队列。细节处理比dp少一点,而且差不多。
时间复杂度
空间复杂度
代码
方法一
///满足最优子结构,顺序上没有后效性可以dp #include <bits/stdc++.h> using namespace std; int l[307], c[307]; unordered_map<int, int> dp[307]; int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n; cin >> n; for (int i = 1;i <= n;i++) cin >> l[i]; for (int i = 1;i <= n;i++) cin >> c[i]; dp[0][0] = 0;///gcd单位元 for (int i = 1;i <= n;i++) { for (auto [x, y] : dp[i - 1]) {///向后传递,不能写找前继承 if (!dp[i].count(x)) dp[i][x] = 0x3f3f3f3f; dp[i][x] = min(dp[i][x], y); int d = gcd(l[i], x); if (!dp[i].count(d)) dp[i][d] = 0x3f3f3f3f; dp[i][d] = min(dp[i][d], y + c[i]); } } if (dp[n].count(1)) cout << dp[n][1] << '\n'; else cout << -1 << '\n'; return 0; }
方法二
///也可以写成优先队列bfs,好处是不用考虑后效性,以花费从小到大为顺序扩展,复杂度玄学 #include <bits/stdc++.h> using namespace std; int n; int l[307], c[307]; unordered_set<int> vis; struct node { int l; int c; friend bool operator<(const node &a, const node &b) { return a.c > b.c; } }; int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } int bfs() { priority_queue<node> pq; pq.push({ 0,0 }); while (!pq.empty()) { node cur = pq.top(); pq.pop(); if (cur.l == 1) return cur.c; if (vis.count(cur.l)) continue; vis.insert(cur.l);///经过后再锁 for (int i = 1;i <= n;i++) { int d = gcd(l[i], cur.l); if (vis.count(d)) continue; pq.push({ d,cur.c + c[i] }); } } return -1; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); cin >> n; for (int i = 1;i <= n;i++) cin >> l[i]; for (int i = 1;i <= n;i++) cin >> c[i]; cout << bfs() << '\n'; return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16581767.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧