Acwing 180. 排书
给定 \(n\) 本书,编号为 1∼n。
在初始状态下,书是任意排列的。
在每一次操作中,可以抽取其中连续的一段,再把这段插入到其他某个位置。
我们的目标状态是把书按照 1∼n 的顺序依次排列。
求最少需要多少次操作。
解:
考虑每一步决策数量,当抽取长度为 \(len\) 的一段时,有 \(n - len+ 1\) 种抽法,对于每种抽法,有 \(n - len\) 种放法。另外,将某一段向前移动,等价于将跳过的那段向后移动,因此每种移动方式被算了两遍,所以每个状态总共的分支数量是:
\]
题目要求最多\(4\)次算出答案,那么就是\(560^4\),又由于\(IDA \,\, star\) 有估价函数,那么实际上数据量会更小。
对于估价函数:答案应该是\(1,2,3,4,5...,n\)的形式,所以每个数\(a[i]\)的的后边应该是\(a[i + 1]\),满足\(a[i] + 1 = a[i + 1]\),不满足就记录一下这种情况的数量\(cnt\),而我们每操作一次最多可以改变三个位置的地方,即\(l(当前段的左边),r(当前段的右边),k(插入的位置)\)三个位置的顺序,因此最多一次可以改变三个,即终点到当前状态下的预估距离,那么最优情况下我们操作一个序列改变三个,那么估价函数就设置为\(f(x) = \lceil \cfrac{cnt}{3} \rceil\),如果估价函数 \(f(x) = 0\),说明序列已经有序。
考虑\(IDA star\)与\(A star\)。
\(IDA star\)是迭代加深和估价函数结合版
// Problem: 排书
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/182/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
const int N = 15;
int n;
int q[N];
int w[5][N];
int f() {
int cnt = 0;
for (int i = 0; i + 1 < n; i++) {
if (q[i + 1] != q[i] + 1) cnt++;
}
return (cnt + 2) / 3;
}
bool dfs(int depth, int max_depth) {
if (depth + f() > max_depth) return false;
if (f() == 0) return true;
for (int len = 1; len <= n; len++) {
for (int l = 0; l + len - 1 < n; l++) {
int r = l + len - 1;
for (int k = r + 1; k < n; k++) { //把当前区间放到哪个位置上
memcpy(w[depth], q, sizeof q);
int y = l;
for (int x = r + 1; x <= k; x++, y++) q[y] = w[depth][x];
for (int x = l; x <= r; x++, y++) q[y] = w[depth][x];
if (dfs(depth + 1, max_depth)) return true;
memcpy(q, w[depth], sizeof q);
}
}
}
return false;
}
int main() {
int t;
cin >> t;
while (t--) {
cin >> n;
for (int i = 0; i < n; i++) cin >> q[i];
int depth = 0;
while (depth < 5 && !dfs(0, depth)) depth++;
if (depth == 5) puts("5 or more");
else cout << depth << endl;
}
return 0;
}
\(A star\)
注意:
在哈希表中嵌套结构体的时候需要重载相应的函数,例如哈希函数,所以这里不如直接自己实现哈希函数。
还要注意堆中嵌套结构体重载一下小于号的方式。
// Problem: 排书
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/182/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
const int N = 15;
int n, P = 17;
int w[5][N];
struct Node {
int q[N], step, f;
bool operator < (const Node &x) const{
return f > x.f;
}
}start;
//在unordered_set中嵌套结构体还是要重写Hash函数,不如直接这样写
ULL getHash(Node x) {
ULL res = 0;
for (int i = 0; i < n; i++) {
res = res * P + x.q[i];
}
return res;
}
int f(Node x) {
int cnt = 0;
for (int i = 0; i + 1 < n; i++) {
if (x.q[i + 1] != x.q[i] + 1) cnt++;
}
return (cnt + 2) / 3;
}
int astar() {
unordered_set<ULL> st;
priority_queue<Node> heap;
start.step = 0, start.f = f(start);
heap.push(start); st.insert(getHash(start));
while (heap.size()) {
auto t = heap.top();
heap.pop();
if (t.f >= 5) return 5;
if (f(t) == 0) return t.step;
for (int len = 1; len <= n; len++) {
for (int l = 0; l + len - 1 < n; l++) {
int r = l + len - 1;
for (int k = r + 1; k < n; k++) {
Node v;
for (int d = 0; d < n; d++) v.q[d] = t.q[d];
int y = l;
for (int x = r + 1; x <= k; x++, y++) v.q[x] = t.q[y];
for (int x = l; x <= r; x++, y++) v.q[x] = t.q[y];
if (st.count(getHash(v))) continue;
st.insert(getHash(v));
v.step = t.step + 1;
v.f = v.step + f(v);
heap.push(v);
}
}
}
}
return 5;
}
int main() {
int t;
cin >> t;
while (t--) {
cin >> n;
for (int i = 0; i < n; i++) cin >> start.q[i];
int res = astar();
if (res >= 5) puts("5 or more");
else cout << res << endl;
}
return 0;
}
Acwing 180. 排书的更多相关文章
- AcWing 180. 排书
AStar 最坏情况\(O(log_2560 ^ 4)\) 用\(AStar\)算法做了这题,程序跑了\(408ms\). 相比于\(IDA*\)的\(100ms\)左右要慢上不少. 且\(A*\)由 ...
- AcWing 1023. 买书 完全背包
//完全背包 求方案数目 //f[i][j] 只从前i个物品中选,且总体积恰好为j的方案的集合 //f[i][j]=f[i-1][j]+f[i-1][j-v*1]+f[i-1][j-v*2]+...f ...
- AcWing 【算法提高课】笔记02——搜索
搜索进阶 22.4.14 (PS:还有 字串变换 A*两题 生日蛋糕 回转游戏 没做) 感觉暂时用不上 BFS 1. Flood Fill 在线性时间复杂度内,找到某个点所在的连通块 思路 统计连通块 ...
- python库-collections模块Counter类
Counter类主要是用来跟踪值出现的次数.它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value. demo: all_words = [] # 列表里面是汉字(可 ...
- [No00005F]读书与心智
读千卷书,行万里路,不够…还得有个对谈者相伴,才更有意思.十月七号晚上,与友人谈读书,线上直播,三百观众相伴,四小时畅谈,不亦乐乎! Part1:读书的载体 散发出最浓郁的知识芬芳和铭刻下最隽永的历史 ...
- 本周实验的PSP0过程文档
项目计划总结: 日期/任务 听课 编写程序 阅读相关书籍 日总计 周一 110 60 ...
- CodeForces 294B Shaass and Bookshelf 【规律 & 模拟】或【Dp】
这道题目的意思就是排两排书,下面这排只能竖着放,上面这排可以平着放,使得宽度最小 根据题意可以得出一个结论,放上这排书的Width 肯定会遵照从小到大的顺序放上去的 Because the total ...
- 第三周pspo过程文档
团队协作: 日期/任务 听课 编写程序 阅读相关书籍 日总计 周一 110 60 ...
- pspo过程文档
项目计划总结: 日期/任务 听课 编写程序 阅读相关书籍 日总计 周一 110 60 ...
- 《Word排版艺术》读后感,兼谈LaTeX
我有两年多的LaTeX使用经验,用它排实验报告.毕业论文和书籍(半本):Word的使用时间长一些,但真正用好也不过是近一两年的事.这两个软件我都 用得很熟,我想我可以一边谈谈读<Word排版艺术 ...
随机推荐
- nuitka 将程序编译为单个exe
原文链接:https://github.com/Nuitka/Nuitka 在Windows上,有两种模式,一种是将其复制到您公司指定的AppData,也将其用作缓存,另一种是在临时目录中进行.您需要 ...
- 医疗知识图谱问答 ——Neo4j 基本操作
前言 说到问答机器人,就不得不说一下 ChatGPT 啦.一个预训练的大预言模型,只要是人类范畴内的知识,似乎他回答得都井井有条,从写文章到写代码,再到解决零散琐碎的问题,不光震撼到我们普通人,就百度 ...
- RobotFrameWork环境搭建及使用
RF环境搭建 首先安装python并且配置python环境变量 pip install robotframework pip install robotframework-ride 生产桌面快捷方式 ...
- 优化 Redis 集群缓存分配:解决节点间分配不均导致内存溢出问题
一.Redis 集群部署简介 在现代应用程序中,缓存被广泛应用以提高性能和减轻后端数据库的压力.本文将探讨面对 Redis 集群缓存分配不均问题时的解决方法. 我们的 Redis 集群部署包括 3 主 ...
- 工具—批量备案信息查询并生成fofa查询语句
描述: 1.可以输入一个或多个公司名或域名或备案号,得到备案信息(备案公司名,备案公司网站url,备案号,域名类型,审核时间) 2.读取生成的信息并转为fofa语句,方便了指定目标的信息收集速度 工具 ...
- Vue【原创】整合el-dialog,可拖动可全屏最大化弹出框
项目中很多时候需要弹出框可以拖动并且可最大化,el-dialog是不满足的,这边采用指令的方式进行拓展. 先来个效果图: 首先来个v-darg指令: 1 import Vue from 'vue' 2 ...
- SpringBoot使用@Async注解8大坑点
前言 SpringBoot中,@Async注解可以实现异步线程调用,用法简单,体验舒适. 但是你一定碰到过异步调用不生效的情况,今天,我就列出90%的人都可能会遇到的8大坑点. 正文 1.未启用异步支 ...
- MySQL的字段数量以及长度限制
一.InnoDB行格式 行格式 紧凑的存储特性 增强的可变长度列存储 大型索引键前缀支持 压缩支持 支持的表空间类型 REDUNDANT N N N N system, file-per-table, ...
- 【matplotlib基础】--动画
matplotlib的动画一直是一个强大但使用频率不高的功能,究其原因,一方面展示动画需要一定的媒介,没有图形和文字展示方便:二来大家更关心的是分析结果的最终图表,图表的动态展示则没有那么重要. 不过 ...
- Python基于Flask的高校舆情分析,舆情监控可视化系统
一.前言在当今社会,舆情监控越来越被重视.随着互联网技术的发展,我们从传统媒体渠道.官方报告.调查问卷等方式搜集到的舆情信息,逐渐被网络上的内容所替代.因为网络上的内容传播速度快.及时性强.覆盖范围广 ...