CF510D Fox And Jumping
题目
见链接。
题解
方法一
知识点:背包dp,STL。
题目意思是让我们判断能否从这些数中选出一些数使得选的数公共gcd为 \(1\),如果可以输出最小花费。
一眼背包dp,但要map超大背包优化,因为数字很大 \(10^9\) ,显然无法直接在第二维放下。
设 \(dp[i][j]\) 表示考虑到第 \(i\) 个数,所有数的gcd为 \(j\) 的情况。 因为用map优化了,没法填表了,因为每行都的元素都不确定,应该用刷表法,用这一行结果推到下一行。转移方程为:
dp[i][x] &= \min(dp[i-1][x],dp[i][x])\\
dp[i][gcd(l[i],x)] &= \min(dp[i-1][x] + c[i],dp[i][gcd(l[i],x)])
\end{aligned}
\]
前者表示不选第 \(i\) 个数的转移,后者表示选了第 \(i\) 个数的转移。
因为不能 memset 初始化正无穷,因此要做到循环中对第一次出现的状态初始化。同时,这也是解决数组太大每次全部初始化很费时间情况下的一种技巧。
注意为了方便,初始化了 \(dp[0][0] = 0\) 。用于每次选一个数自己是第一个数的情况,能正确被标记而不用特判,即 \(gcd(l[i],0) = l[i]\)。因为在我们写的gcd函数里, \(0\) 可以当作特殊的单位元,特殊之处在于其应该出现在函数的后面一个位置,即 \(gcd(a,0)\) ,否则会出错。
时间复杂度 \(O(n*玄学)\) ,qwq最大公约数种类不知道怎么算
空间复杂度 \(O(玄学)\)
方法二
知识点:BFS,优先队列,记忆化搜索。
说白了就是记忆化搜索,用广搜做最短路,求花费最小的路径,因此用优先队列。细节处理比dp少一点,而且差不多。
时间复杂度 \(O(能过而且更快)\)
空间复杂度 \(O(能过)\)
代码
方法一
///满足最优子结构,顺序上没有后效性可以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;
}
CF510D Fox And Jumping的更多相关文章
- Codeforces Round #290 (Div. 2) D. Fox And Jumping dp
D. Fox And Jumping 题目连接: http://codeforces.com/contest/510/problem/D Description Fox Ciel is playing ...
- Fox And Jumping
Fox And Jumping 题目链接:http://codeforces.com/problemset/problem/512/B dp 若所选卡片能到达区间内任意点,那么所选卡片的最大公约数为1 ...
- CodeForces - 512B Fox And Jumping[map优化dp]
B. Fox And Jumping time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- Codeforces510 D. Fox And Jumping
Codeforces题号:#510D 出处: Codeforces 主要算法:map+DP 难度:4.6 思路分析: 题意:给出n张卡片,分别有l[i]和c[i].在一条无限长的纸带上,你可以选择花c ...
- 【Cf #290 B】Fox And Jumping(dp,扩展gcd)
根据裴蜀定理,当且仅当选出来的集合的L[i]的gcd等于1时,才能表示任何数. 考虑普通的dp,dp[i][j]表示前i个数gcd为j的最少花费,j比较大,但状态数不多,拿个map转移就好了. $ \ ...
- 【codeforces 510D】Fox And Jumping
[题目链接]:http://codeforces.com/contest/510/problem/D [题意] 你可以买n种卡片; 每种卡片的花费对应c[i]; 当你拥有了第i种卡片之后; 你可以在任 ...
- Codeforces 512B: Fox And Jumping
题目链接 题意说的是,有n种卡片,使用第i种卡片可以使当前自己在数轴上的位置移动 l[i],要获得使用第i种卡片的代价是 c[i],求能使自己移动到数轴上任意位置的最小代价,如果不可能则输出-1 当前 ...
- CF习题集三
CF习题集三 一.CF8C Looking for Order 题目描述 \(Lena\)喜欢秩序井然的生活.一天,她要去上大学了.突然,她发现整个房间乱糟糟的--她的手提包里的物品都散落在了地上.她 ...
- 数论专项复习(一)扩展欧几里得算法(exgcd)
简介 扩展欧几里得算法(简称扩欧,exgcd),用来求下列方程的一组解: \[ax+by=(a,b) \] 算法介绍 1. 裴蜀定理 裴蜀定理(Bézout's lemma):若 \(a\in \ma ...
- CodeForces Round #290 Div.2
A. Fox And Snake 代码可能有点挫,但能够快速A掉就够了. #include <cstdio> int main() { //freopen("in.txt&quo ...
随机推荐
- [转帖]被误解的CPU利用率、超线程、动态调频 —— CPU 性能之迷 Part 1
https://blog.mygraphql.com/zh/notes/hw/hyper-threading/ 引 性能测试.压力测试.业务系统性能容量评估.这 3 件事,可以认为是大部分程序员/软件 ...
- [转帖]Oracle进程中的 LOCAL=NO 和 LOCAL=YES
https://www.cnblogs.com/wjoyxt/p/3780860.html 我们在服务器上用sqlplus 连接数据库,在查看进程,会多出一条记录: oracle 16007 1600 ...
- [转帖]《Linux性能优化实战》笔记(十五)—— 磁盘IO的工作原理
前一篇介绍了文件系统的工作原理,这一篇来看看磁盘IO的工作原理 一. 磁盘 1. 按存储介质分类 磁盘是可以持久化存储的设备,根据存储介质的不同,常见磁盘可以分为两类:机械磁盘和固态磁盘. 机械磁盘, ...
- [转帖]解释docker单机部署kraft模式kafka集群时,尝试各种方式的网络broker全部不通而启动失败的原因,并提示常见bug关注点
现象: controller节点与其他两个broker的通信失败.公网ip,宿主机ip,服务名,各种网络方式,都无法成功. 两点提示: 1.bug原因:因为单机内存不够用,设置了较低的 KAFKA_H ...
- Oracle AWR学习之二-利用ChatGPT编写一键获取AWR报告的脚本
Oracle AWR学习之二-ChatGPT提升效率之n 背景 之前生成awr报告比较麻烦, 想着能够一键生成. 再辅以部分shell或者是python处理就可以进行细致的分析. 这一块其实还是比较简 ...
- 【转帖】linux 软连接的使用
https://www.cnblogs.com/sueyyyy/p/10985443.html 软连接是linux中一个常用命令,它的功能是为某一个文件在另外一个位置建立一个同不的链接. 具体用法是: ...
- [转帖]Redis 核心篇:唯快不破的秘密
文章系转载,方便整理和归纳,源文地址:https://z.itpub.net/article/detail/4B5A03BDDBE9A2BC3E080E278FE4D21E 以下文章来源于码哥字节 , ...
- MySQL知识点总结(完整版)
MySQL学习笔记 登录和退出MySQL服务器 # 登录MySQL $ mysql -u root -p12345612 # 退出MySQL数据库服务器 exit; 基本语法 -- 显示所有数据库 s ...
- C# 使用字典将枚举转换为String
枚举 public enum ColorType { Red = 10, Blue = 20, Green = 30, Yellow = 40, } String var A1 = "AAA ...
- C/C++ 原生套接字抓取FTP数据包
网络通信在今天的信息时代中扮演着至关重要的角色,而对网络数据包进行捕获与分析则是网络管理.网络安全等领域中不可或缺的一项技术.本文将深入介绍基于原始套接字的网络数据包捕获与分析工具,通过实时监控网络流 ...