给定 \(n\) 本书,编号为 1∼n。

在初始状态下,书是任意排列的。

在每一次操作中,可以抽取其中连续的一段,再把这段插入到其他某个位置。

我们的目标状态是把书按照 1∼n 的顺序依次排列。

求最少需要多少次操作。

解:

考虑每一步决策数量,当抽取长度为 \(len\) 的一段时,有 \(n - len+ 1\) 种抽法,对于每种抽法,有 \(n - len\) 种放法。另外,将某一段向前移动,等价于将跳过的那段向后移动,因此每种移动方式被算了两遍,所以每个状态总共的分支数量是:

\[\sum\limits_{len = 1}^n \cfrac{(n - len + 1) * (n - len)}{2} = \cfrac{15*14 + 14*13 + 13*12...+2*1}{2} = 560
\]

题目要求最多\(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. 排书的更多相关文章

  1. AcWing 180. 排书

    AStar 最坏情况\(O(log_2560 ^ 4)\) 用\(AStar\)算法做了这题,程序跑了\(408ms\). 相比于\(IDA*\)的\(100ms\)左右要慢上不少. 且\(A*\)由 ...

  2. 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 ...

  3. AcWing 【算法提高课】笔记02——搜索

    搜索进阶 22.4.14 (PS:还有 字串变换 A*两题 生日蛋糕 回转游戏 没做) 感觉暂时用不上 BFS 1. Flood Fill 在线性时间复杂度内,找到某个点所在的连通块 思路 统计连通块 ...

  4. python库-collections模块Counter类

    Counter类主要是用来跟踪值出现的次数.它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value. demo: all_words = [] # 列表里面是汉字(可 ...

  5. [No00005F]读书与心智

    读千卷书,行万里路,不够…还得有个对谈者相伴,才更有意思.十月七号晚上,与友人谈读书,线上直播,三百观众相伴,四小时畅谈,不亦乐乎! Part1:读书的载体 散发出最浓郁的知识芬芳和铭刻下最隽永的历史 ...

  6. 本周实验的PSP0过程文档

    项目计划总结:       日期/任务      听课        编写程序         阅读相关书籍 日总计          周一      110           60         ...

  7. CodeForces 294B Shaass and Bookshelf 【规律 & 模拟】或【Dp】

    这道题目的意思就是排两排书,下面这排只能竖着放,上面这排可以平着放,使得宽度最小 根据题意可以得出一个结论,放上这排书的Width 肯定会遵照从小到大的顺序放上去的 Because the total ...

  8. 第三周pspo过程文档

    团队协作:     日期/任务      听课        编写程序         阅读相关书籍 日总计          周一      110          60             ...

  9. pspo过程文档

    项目计划总结:       日期/任务      听课        编写程序         阅读相关书籍 日总计          周一      110          60         ...

  10. 《Word排版艺术》读后感,兼谈LaTeX

    我有两年多的LaTeX使用经验,用它排实验报告.毕业论文和书籍(半本):Word的使用时间长一些,但真正用好也不过是近一两年的事.这两个软件我都 用得很熟,我想我可以一边谈谈读<Word排版艺术 ...

随机推荐

  1. Feign自定义重试策略及超时时间

    背景 feign可以配置重试策略及超时时间,但是无法根据业务场景动态的设置.可能会引起接口幂等,无效重试资源耗费,大数据量耗时操作报超时异常等问题.所以需要更细粒度的重试策略及超时时间配置. 自定义重 ...

  2. [loki]轻量级日志聚合系统loki快速入门

    前言 简述:loki是由grafana开源的日志聚合系统,相较于ELK.EFK更轻量. loki特性: 不对日志进行全文索引.通过存储压缩非结构化日志和仅索引元数据,Loki 操作起来会更简单,更省成 ...

  3. JVM常用运行时参数说明

    前言 仅列出常用JVM调优参数,更多请转文末的官方文档链接. 堆内存 -Xmx,设置最大堆内存,默认为物理内存的1/4.示例:-Xmx4096m,设置为4G -Xms,设置初始内存,默认为物理内存的1 ...

  4. ignite

    目录 简介 运行 制作vm文件系统 制作vm基础文件系统文件 创建contianerdClient 创建cniInstance 拉取基础镜像 创建基础文件系统文件 制作vm内核文件 Create vm ...

  5. Airtest的iOS实用接口介绍

    1. 前言 前段时间Airtest更新了1.3.0.1版本,里面涉及非常多的iOS功能新增和改动,今天想详细跟大家聊一下里面的iOS设备接口. PS:本文示例均使用本地连接的iOS设备,Airtest ...

  6. c# .NET 高级编程 高并发必备技巧(二) - 分布式锁

    上一篇文章简单的介绍了单机的情况下如何进行加锁,防止高并发带来的问题. 然而现实中,一般会高并发的应用,很少会单机部署.当用户量达到一定的程度,分布式.集群部署是必然的选择.在分布式部署的情况下,之前 ...

  7. Domain Admin域名和SSL证书过期监控到期提醒

    基于Python3 + Vue3.js 技术栈实现的域名和SSL证书监测平台 用于解决,不同业务域名SSL证书,申请自不同的平台,到期后不能及时收到通知,导致线上访问异常,被老板责骂的问题 核心功能: ...

  8. vue2和vue3使用echarts时无数据,怎么显示暂无数据图片或文字

    一开始也经历了用v-if和v-show,v-show的话echarts还会留出暂无数据图片的位置,导致echarts变形,v-if在加载和不加载切换时,dom会获取不到:后来也是在网上找的方法,时间有 ...

  9. 文心一言 VS 讯飞星火 VS chatgpt (96)-- 算法导论9.3 1题

    一.用go语言,在算法 SELECT 中,输人元素被分为每组 5 个元素.如果它们被分为每组 7个元素,该算法仍然会是线性时间吗?证明:如果分成每组 3 个元素,SELECT 的运行时间不是线性的. ...

  10. gitbook生成静态页面不跳转

    gitbook页面不跳转 现在可以在localhost:4000/查看自己的网页了.而且生成的网页存在_book文件夹中,下次点击 _book文件夹中的index.html就能打开网页,内容无更新,就 ...