给定 \(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. QLabel类中的常用方法&信号

    setAlignment: 按固定值方式对齐文本 Qt.AlignLeft:水平方向靠左对齐 Qt.AlignRight:水平方向靠右对齐 Qt.AlignCenter:水平方向居中对齐 Qt.Ali ...

  2. TypeChat源码分析:基于大语言模型的定制化 AI Agent 交互规范

    TypeChat源码分析:基于大语言模型的定制化 AI Agent 交互规范 本文深入介绍了微软最近发布的 TypeChat 项目,该项目允许开发者定义大语言模型返回的响应结构.通过分析源代码,探讨了 ...

  3. LaZagne:一键抓取目标机器上的所有明文密码的神器

    LaZagne 介绍 功能 LaZagne 是用于获取存储在本地计算机上的大量密码的开源应用程序. 每个软件都使用不同的技术(纯文本.API.自定义算法.数据库等)存储其密码.LaZagne 的作用就 ...

  4. 洛谷 P1336 最佳课题选择 题解

    P1336 最佳课题选择 题解 状态:考虑\(f_{i,j}\)表示前\(i\)种论文里面,一共写了\(j\)篇,的最少花费时间. 转移策略:我们一次考虑每一种论文写多少篇.假设写\(k\)篇,\(k ...

  5. H5用canvas放烟花

    很久很久以前的一个很流行的java Applet放烟花效果,当初移到android过,这次摸鱼时间翻译成js代码,用canvas实现这么多年,终于能大致看懂这代码了, 已经实现透明效果,只需要给bod ...

  6. Selenium 学习笔记

    Selenium 学习笔记 Selenium 框架是时下在 Web 领域中被使用得最为广泛的自动化测试工具集之一,它能帮助程序员们面向指定的 Web 前端应用快速地开发出自动化测试用例,且能实现跨各种 ...

  7. 【微信自动化】使用c#实现微信自动化

    引言 上个月,在一个群里摸鱼划水空度日,看到了一个老哥分享的一个微信自动化的一个类库,便下载了他的Demo,其本意就是模拟鼠标来操作UI,实现UI自动化:然后自己在瞎琢磨研究,写了一个简单的例子,用来 ...

  8. linux上搭建Nacos集群(步骤详细,linux小白也能搞定)

    (1)nacos官网:https://github.com/alibaba/nacos/releases/tag/1.2.1下载nacos安装包到window本地(后缀为tar.zip) (2)在li ...

  9. MySQL-通过存储过程来添加和删除分区(List分区)

    1.背景原因 当前MySQL不支持在添加和删除分区时,使用IF NOT EXISTS和IF EXISTS.所以在执行调度任务时,直接通过ADD PARTITION和DROP PARTITION不可避免 ...

  10. Spring Boot虚拟线程与Webflux在JWT验证和MySQL查询上的性能比较

    早上看到一篇关于Spring Boot虚拟线程和Webflux性能对比的文章,觉得还不错.内容较长,我就不翻译了,抓重点给大家介绍一下这篇文章的核心内容,方便大家快速阅读. 测试场景 作者采用了一个尽 ...