给定 \(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. 奇分频电路如何实现? 负沿触发&非负沿触发

    请设计一个奇分频电路,占空比为50%? 以下给出解答: 1.带负沿触发 module div //带负沿触发 #(parameter N = 5) //定义分频参数 ( input sys_clk , ...

  2. 代码随想录算法训练营第四天| LeetCode 24. 两两交换链表中的节点 19.删除链表的倒数第N个节点 142.环形链表II

    24. 两两交换链表中的节点         卡哥建议:用虚拟头结点,这样会方便很多. 本题链表操作就比较复杂了,建议大家先看视频,视频里我讲解了注意事项,为什么需要temp保存临时节点. 题目链接/ ...

  3. LangChain:打造自己的LLM应用

    1.LangChain是什么 LangChain是一个框架,用于开发由LLM驱动的应用程序.可以简单认为是LLM领域的Spring,以及开源版的ChatGPT插件系统.核心的2个功能为: 1)可以将 ...

  4. 从浅入深了解.NET Core MVC 2.x全面教程

    一.基础 1.默认配置 使用Kestrel Web Server ASP.NET Core内置--跨平台 IIS集成 UseIIS() UseIISIntergration() Log IConfig ...

  5. 【go笔记】TCP编程

    前言 TCP服务端的处理流程 监听端口 接收客户端请求建立连接 创建goroutine处理链接 示例代码:TCP服务端 package main import ( "net" &q ...

  6. 《Pro Git》起步笔记

    @ 目录 什么是版本控制 本地版本控制系统 集中化的版本控制 分布式的版本控制系统 Git简史 Git是什么 安装Git 在Linux上安装 在Windows上安装 初次运行Git前的配置 用户信息 ...

  7. Linux字符界面安装更新VMware Tools

    注:yeesn为我自己的用户名,实际操作中改用自己的用户名 1.切换到虚拟光驱目录 cd /media/yeesn/VMware Tools 2.复制压缩包到桌面 cp VMwareTools-xxx ...

  8. Go/C++/Java中的数组对比

    数组是大多数编程语言中的基本数据结构.然而,不同的编程语言对数组的实现和语义有所不同.以下是 Go.C++ 和 Java 中数组的主要区别: 1. 基本性质 Go: 数组是值类型.赋值或将数组传递给函 ...

  9. Electron-builder打包和自动更新

    Electron-builder打包和自动更新 前言 文本主要讲述如何为 electron 打包出来软件配置安装引导和结合 github 的 release 配置自动更新. electron-buil ...

  10. 利用CI机制管控jar依赖树

    1. 现状·问题 你还记得你排查jar冲突的付出么? 为了有效控制jar包更新带来的未知jar引入和变动,我们经常使用dependency-tree来查看依赖关系排查问题,通常是出现问题再被动分析和排 ...