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 ...
随机推荐
- spring boot 整合kafka
本文为博主原创,未经允许不得转载: 1. 引入spring boot kafka依赖 <dependency> <groupId>org.springframework.kaf ...
- Postman 接口测试配置 Pre-request Script
本文为博主原创,转载请注明出处: Pre-request Script 为Postman预置脚本,用于在postman 发送请求之前执行,封装计算或获取某些请求参数. 1. postman 脚本提供 ...
- 一种基于linux系统的精准流量统计方法
前言: 在linux系统关于流量统计,已经有开源的工具,比如nethogs,nload和iptraf.它们适合我们在PC上直接监控某台设备的流量情况,但并不适合我们应用到自己的程序中去. 如果要在 ...
- Mygin实现分组路由Group
本篇是Mygin第五篇 目的 实现路由分组 为什么要分组 分组控制(Group Control)是 Web 框架应该提供的基础功能之一,对同一模块功能的开发,应该有相同的前缀.或者对一部分第三方接口, ...
- [转帖]一份完整的阿里云 Redis 开发规范,值得收藏!
https://blog.csdn.net/NicolasLearner/article/details/117449847 作者:付磊-起扬 http://yq.aliyun.com/article ...
- [转帖]prometheus node-exporter 全部指标说明
https://www.cnblogs.com/276815076/p/16383615.html Basic CPU / Mem / Disk Info Basic CPU / Mem / Disk ...
- [转帖]警惕Oracle数据库性能“隐形杀手”——Direct Path Read
一. 简介 Oracle 的11g版本正式发布到今天已经10年有余,最新版本也已经到了20c,但是Direct Path Read(直接路径读)导致性能问题的案例仍时有发生,很多12c的用户还是经常遇 ...
- [转帖]Oracle客户端与Oracle数据库兼容矩阵
https://www.cnblogs.com/kerrycode/p/17666025.html Oracle客户端与Oracle数据库之间是有兼容支持关系的,有些低版本的Oracle Client ...
- PMC相关RAID卡信息查看方法
PMC相关RAID卡信息查看方法 摘要 昨天简单整理了LSI相关设备的信息 今天计划学习下PMC相关的RAID卡信息. 也就是偶昨天storcli 查看 controller为0 的情况. 感觉部分服 ...
- 说透IO多路复用模型
作者:京东零售 石朝阳 在说IO多路复用模型之前,我们先来大致了解下Linux文件系统.在Linux系统中,不论是你的鼠标,键盘,还是打印机,甚至于连接到本机的socket client端,都是以文件 ...