AcWing - 96 - 奇怪的汉诺塔 = dp

https://www.acwing.com/problem/content/98/

先考虑三个柱子的汉诺塔问题,设d[i]表示在三个柱子都可以选时,把i个塔从一个柱子移动到另一个柱子的最小移动步数。首先把n-1个塔从A移动到B,然后把n从A移动到C,再把n-1个塔从B移动到C。

d[i]=2*d[i-1]+1

当有四个柱子时,情况稍微改变,设f[i]表示在四个柱子都可以选时,把i个塔从一个柱子移动到另一个柱子的最小移动步数,但是观察到实际上最底层的n-j个塔都是要从A到D的,而其中B和C之一必然要把顶层的塔全部放上才空出另一个塔给n-j中转(当然如果只有n一个的话是不需要中转的)。

所以先把j个塔在四个柱子的情况从A移动到B,然后ACD三个塔把n-j从A移动到D,再把j个塔在四个柱子的情况从B移动到D。

f[i]=min(f[i],2*f[j]+d[n-j])

貌似可以推广到更多柱子。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int d[13], f[13];

int main() {
#ifdef Yinku
    freopen("Yinku.in", "r", stdin);
#endif // Yinku
    d[1] = 1;
    for(int i = 2; i <= 12; ++i)
        d[i] = 2 * d[i - 1] + 1;
    f[1] = 1;
    for(int i = 2; i <= 12; ++i) {
        f[i] = 1e9;
        for(int j = 1; j < i; ++j)
            f[i] = min(f[i], 2 * f[j] + d[i - j]);
    }
    for(int i = 1; i <= 12; ++i)
        printf("%d\n", f[i]);
}

原文地址:https://www.cnblogs.com/Inko/p/11515577.html

时间: 2024-08-07 22:56:56

AcWing - 96 - 奇怪的汉诺塔 = dp的相关文章

96. 奇怪的汉诺塔

d[i]表示在三根木棍的情况下,i个盘子要走d[i]步(注意,d[i] 当前i个盘子,三根木棍均可走) f[i]表示在四根木棍的情况下,i个盘子要走的最短步数f[i]步(注意,f[i] 当前i个盘子,四根木棍均可走) f[j] * 2 或 d[i - 1] * 2 表示拿下j(或i - 1)个盘子放到一个临时棍子上,最后还得放到最终的那个棍子上,所以要乘以2 #include <iostream> #include <cstring> using namespace std; in

BZOJ 1019: [SHOI2008]汉诺塔( dp )

dp(x, y)表示第x根柱子上y个盘子移开后到哪根柱子以及花费步数..然后根据汉诺塔原理去转移... ----------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define X(o) o.pos #define Y(o) o.w t

bzoj1019: [SHOI2008]汉诺塔(dp)

1019: [SHOI2008]汉诺塔 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1739  Solved: 1062[Submit][Status][Discuss] Description 汉诺塔由三根柱子(分别用A B C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形体. 对汉诺塔的一次合法的操作是指:从一根柱子的最上层拿一个盘子放到另一根柱子的最上层,同时要保证被移动的

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

hdu1207 汉诺塔II 简单dp

本文出自:http://blog.csdn.net/svitter 题意:汉诺塔,多了一根柱子,问你寻找最快的移动次数. dp [ n ] = dp [ n - j ] * 2 + pow( 2, j ) - 1; 就是把j个汉诺塔移到一根上dp[ n - j ],然后就是普通的汉诺塔问题,即2^n - 1次移动, 然后把剩下的移动过去dp [ n - j ]. 注意pow(2, j )可能超出long long int范围.写二的次方的时候也可用移位算法. #include <iostream

BZOJ1019 SHOI2008 汉诺塔 一般DP

题意:给定汉诺塔移动的优先级(由大到小且两次操作不移动同一个盘子,则能执行的一定执行)和盘子的数量,求移动次数. 题解:设f[i][j]=将i柱子上j个盘子移动到满足要求的柱子上的步数,g[i][j]=移走i柱子上j个盘子按要求会移动到g[i][j]这个柱子.有两种转移的情况 (以下1 2 3仅作代表以方便叙述,不代表具体的柱子) 1.1柱子上移动i个盘子到3:需要先将i-1个盘子移动到2,再移动第i个盘子到3,再移动2上的i-1个盘子到3——f[1][i]=f[1][i-1]+1+f[2][i

【BZOJ 1019】 1019: [SHOI2008]汉诺塔 (DP?)

1019: [SHOI2008]汉诺塔 Description 汉诺塔由三根柱子(分别用A B C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形体. 对汉诺塔的一次合法的操作是指:从一根柱子的最上层拿一个盘子放到另一根柱子的最上层,同时要保证被移动的盘子一定放在比它更大的盘子上面(如果移动到空柱子上就不需要满足这个要求).我们可以用两个字母来描述一次操作:第一个字母代表起始柱子,第二个字母代表目标柱子.例如,AB就是把柱子A最上

BZOJ_1019_[SCOI2008]_汉诺塔_(DP)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1019 汉诺塔游戏,但是有移动优先级,在不违反原有规则的情况下,给定优先移动目标.求完成游戏所需的步数. 分析 我们用\(f[j][i]\)表示把第\(j\)个柱子上的最上面\(i\)个盘子移走所需的步数,用\(g[j][i]\)表示会移动到哪个柱子上. 那么对于\(f[j][i]\),首先把前\(i-1\)个移出去,步数为\(f[j][i-1]\),记移到了柱子\(y\),这时候再把第\(i

hdu1207 汉诺塔II (DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1207 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往上按大小顺序摞着64片黄金圆盘.上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上.并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一回只能移动一个圆盘.有预言说,这件事完成时宇