题目链接

Description

三塔汉诺塔问题,给一个 \(3 \times 3\) 的矩阵 \(t\),\(t_{i, j}\) 表示从 \(i\) 塔移动一个盘子到 \(j\) 塔的花费。

初始状态 \(n\) 个盘子都在第一个盘子,要求将所有的移到第三个盘子,求最小花费。

Solution

显然可以间接移动,花费有可能更优,先用 Floyd 算法算出从 \(i\) 间接 / 直接移动到 \(j\) 的最小花费,设 \(d_{i,j}\) 表示从 \(i\) 到 \(j\) 的最小花费。

显然无后效性,考虑 \(dp\)。

状态设计

设 \(f_{i,a,b}\) 表示将 \(i\) 个盘子从 \(a\) 移动到 \(b\) 的最小花费。

初始状态

\(f_{1, a, b} = d_{a,b}\) 其余为正无穷

状态转移

不妨设另外一个盘子为 \(c\)。

先把 \(n\) 个盘子看做两个整体:第 \(n\) 个盘子和 \(n - 1\) 个盘子,这样可以 DP 了。

通过观察发现有两个可能成为最优的转移方式:

  • 将 \(n - 1\) 个盘子 \(a \Rightarrow c\),第 \(n\) 个盘子 \(a \Rightarrow b\),然后再把 \(n - 1\) 个盘子 \(c \Rightarrow b\)。
  • \(n - 1\) 个盘子 \(a \Rightarrow b\),第 \(n\) 个盘子 \(a \Rightarrow c\),\(n - 1\) 个盘子 \(b \Rightarrow a\),第 \(n\) 个盘子 \(c \Rightarrow b\),\(n - 1\) 个盘子 \(a \Rightarrow b\)。

其他的转移一定是这两种 + 反复横跳形成的。

将上面的方式翻译一下,即:

  • \(f_{i, a, b} \gets f_{i - 1, a,c} + t_{a,b} + f_{i - 1, c, b}\)

  • \(f_{i, a, b} \gets f_{i - 1, a,b} + t_{a,c} + f_{i - 1, b, a} + t_{c,b} + f_{i - 1, a, b}\)

值得注意的是这里不能用 \(d\),因为其他盘子不是空的,不能作为间接量。

时间复杂度

\(O(N)\)

Tips

注意开 long long !

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std; const int N = 45; typedef long long LL; int t[3][3], g[3][3], n;
LL f[N][3][3]; int main() {
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++) scanf("%d", &t[i][j]), g[i][j] = t[i][j];
scanf("%d", &n);
for (int k = 0; k < 3; k++)
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
t[i][j] = min(t[i][j], t[i][k] + t[k][j]);
memset(f, 0x3f, sizeof f);
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
f[1][i][j] = t[i][j]; for (int i = 2; i <= n; i++) {
for (int a = 0; a < 3; a++) {
for (int b = 0; b < 3; b++) {
if (a == b) continue;
int c = 3 - a - b;
f[i][a][b] = min(f[i - 1][a][c] + g[a][b] + f[i - 1][c][b], f[i - 1][a][b] + g[a][c] + f[i - 1][b][a] + g[c][b] + f[i - 1][a][b]);
}
}
}
printf("%lld\n", f[n][0][2]);
return 0;
}

CF392B Tower of Hanoi的更多相关文章

  1. poj 3601 Tower of Hanoi

    Tower of Hanoi Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 1853   Accepted: 635 De ...

  2. python递归三战:Sierpinski Triangle、Tower of Hanoi、Maze Exploring

    本文已做成视频教程投稿b站(视频版相对文本版有一些改进),点击观看视频教程 本文主要通过三个实例来帮助大家理解递归(其展示动画已上传B站): 谢尔宾斯基三角形(Sierpinski Triangle) ...

  3. 汉诺塔问题(The Tower of Hanoi)的递归算法与非递归算法

    非递归算法: 根据圆盘的数量确定柱子的排放顺序: 若n为偶数,按顺时针方向依次摆放 A B C: 若n为奇数,按顺时针方向依次摆放 A C B. 然后进行如下操作: (1)按顺时针方向把圆盘1从现在的 ...

  4. Tower of Hanoi问题

    [问题描述] 有A, B, C三个塔座,A上套有n个直径不同的圆 盘,按直径从小到大叠放,形如宝塔,编号1, 2, 3 … n. 要求将n个圆盘从A移到C,叠放顺序不变,移动过程中遵循 下列原则: w ...

  5. [POJ1958][Strange Tower of Hanoi]

    题目描述 求解 \(n\) 个盘子 \(4\) 座塔的 Hanoi 问题最少需要多少步 问题分析 考虑 \(3\) 座塔的 Hanoi 问题,记 \(f[i]\) 表示最少需要多少步, 则 \(f[i ...

  6. One usage of recurison: the tower of Hanoi

    Statements: This blog was written by me, but most of content  is quoted from book[Data Structure wit ...

  7. 汉诺塔 Tower of Hanoi

    假设柱子标为A,B.C.要由A搬至C,在仅仅有一个盘子时,就将它直接搬至C:当有两个盘子,就将B作为辅助柱.假设盘数超过2个.将第二个下面的盘子遮起来,就非常easy了.每次处理两个盘子,也就是:A- ...

  8. codeforces 392B Tower of Hanoi

    把前n个碟子从第一个塔移动到第三个塔有两种方法: 1.把前n-1个移动到第二个塔,把第n个移动到第三个塔,然后把前n-1个从第二个移动到第三个: 2.把前n-1个移动到第三个塔,把第n个移动到第二个塔 ...

  9. codeforces392B

    CF392B Tower of Hanoi 题意翻译 河内塔是一个众所周知的数学难题.它由三根杆和一些可以滑动到任何杆上的不同尺寸的圆盘组成.难题从一个整齐的杆中开始,按照尺寸从小到大的顺序排列,最小 ...

随机推荐

  1. python之 《进程之间数据交互和进程池》

    1.进程q 进程呢就相当于一个房子,线程就相当于是房子里面在工作的人,那么一个房子的空间对于房子里面的人来说是共享的, 现在是多进程,也就是说有许多房子,很显然这个房子的空间只属于这个房子,不会属于其 ...

  2. EF Core 二 、 入门 EF Core

    入门EF Core 我们将开始真正的EF之旅了,这里使用SqlServer数据,然后DbFirst: 为嘛使用SqlServer,目前公司的整体业务全部在SqlSever,所以很多产品业务都是依托于这 ...

  3. Python_多进程_pool进程池

    多进程典型案例: 1.将子进程的进程名作为列表中的元素,在父进程中遍历(异步)执行 #coding: utf-8 from multiprocessing import Pool import os, ...

  4. HDU100题简要题解(2030~2039)

    HDU2030 汉字统计 题目链接 Problem Description 统计给定文本文件中汉字的个数. Input 输入文件首先包含一个整数n,表示测试实例的个数,然后是n段文本. Output ...

  5. SQL注入学习-Dnslog盲注

    1.基础知识 1.DNS DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的 ...

  6. 算法学习笔记:Kosaraju算法

    Kosaraju算法一看这个名字很奇怪就可以猜到它也是一个根据人名起的算法,它的发明人是S. Rao Kosaraju,这是一个在图论当中非常著名的算法,可以用来拆分有向图当中的强连通分量. 背景知识 ...

  7. MathType如何输入微分上的点

    作为被老师们青睐的公式编辑器,MathType可以帮助插入各种数学符号和编辑数学公式,从而提高数学试卷的编写效率.但是作为新手,在编辑公式的时候难免有困难,比如就有人问:如何输入微分上的点?其实也是有 ...

  8. Calling unknown method: app\modules\mobile\controllers\CompanyController::redirect()

    $this->redirect(['default/error']); Yii::$app->end();上边的代码出现 Calling unknown method: app\modul ...

  9. Forethought Future Cup - Final Round (Onsite Finalists Only) C. Thanos Nim 题解(博弈+思维)

    题目链接 题目大意 给你n堆石子(n为偶数),两个人玩游戏,每次选取n/2堆不为0的石子,然后从这n/2堆石子中丢掉一些石子(每一堆丢弃的石子数量可以不一样,但不能为0),若这次操作中没有n/2堆不为 ...

  10. Linux下的MediaWiki的部署启动遇到的问题与解决方案

    1. MySQL安装不成功 解决方案:https://bbs.csdn.net/topics/394377536 2. no space left on device ubuntu 解决方案:http ...