汉诺塔(BZOJ)

P4285 [SHOI2008]汉诺塔

居然是省选题,还是DP!(我的DP菜得要死,碰见就丢分)

冥思苦想了1h+ \(\to\) ?!

就是普通的hanoi NOI or HNOI? DP加上一个乱搞的数组,然后我还写反了一次,就gg了。

大概思路:

\(dp_{i,j}\)表示从柱子i移动j个盘子的最优解,\(f_{i,j}\) 表示从柱子i移动j个盘子到哪个柱子最优。然后就可以转移了!

先把i-1个盘子从x移到 \(y=f_{x,i-1}\) ,设另一根为z,然后分类:

1.\(f_{y,i-1}=y\),直接舍掉,不用DP了。

2.\(f_{y,i-1}=z\),那么把i-1个盘子从x移到y,把第i个移到z,然后把y上的i-1个移到z。

\(dp_{x,i}=dp_{x,i-1}+1+dp_{y,x-1},f_{i,j}=z\)

3.\(f_{y,i-1}=x\),把i-1个盘子先从x移到z,再把第i-1个从y移到x,再把z上的第i个移到y,再把x上i-1个的移到y

\(dp_{x,i}=dp_{x,i-1}+1+dp_{y,i-1}+1+dp_{x,i-1},f_{i,j}=y\)

最后 \(dp_{1,n}\) 就是答案

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=35;
char s[5];
int n;
int dp[N][N],f[4][N],from[7],to[7];
signed main()
{
scanf("%lld",&n);
for(int i=1;i<=6;++i)
{
scanf("%s",s);
from[i]=s[0]-'A'+1,to[i]=s[1]-'A'+1;
}
for(int i=6;i>=1;--i)f[from[i]][1]=to[i];
dp[1][1]=dp[2][1]=dp[3][1]=1;
for(int i=2;i<=n;++i)
{
for(int j=1;j<=3;++j)
{
int x=j,y=f[x][i-1],z=6-x-y;
if(f[y][i-1]==z)
{
dp[x][i]=dp[y][i-1]+1+dp[x][i-1];
f[x][i]=z;
}
if(f[y][i-1]==x)
{
dp[x][i]=dp[y][i-1]+1+dp[x][i-1]+1+dp[x][i-1];
f[x][i]=y;
}
}
}
printf("%lld\n",dp[1][n]);
return 0;
}

BZOJ1019 汉诺塔/洛谷P4285 [SHOI2008]汉诺塔的更多相关文章

  1. bzoj1019 / P4285 [SHOI2008]汉诺塔

    P4285 [SHOI2008]汉诺塔 递推 题目给出了优先级,那么走法是唯一的. 我们用$0,1,2$代表$A,B,C$三个柱子 设$g[i][x]$为第$x$根柱子上的$i$个盘子,经过演变后最终 ...

  2. 洛谷P1242 新汉诺塔(dfs,模拟退火)

    洛谷P1242 新汉诺塔 最开始的思路是贪心地将盘子从大到小依次从初始位置移动到目标位置. 方法和基本的汉诺塔问题的方法一样,对于盘子 \(i\) ,将盘子 \(1\to i-1\) 放置到中间柱子上 ...

  3. P4285 [SHOI2008]汉诺塔 题解 (乱搞)

    题目链接 P4285 [SHOI2008]汉诺塔 解题思路 提供一种打表新思路 先来证明一个其他题解都没有证明的结论:\(ans[i]\)是可由\(ans[i-1]\)线性递推的. (\(ans[i] ...

  4. 洛谷P1282 多米诺骨牌 (DP)

    洛谷P1282 多米诺骨牌 题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中 ...

  5. Bzoj1018/洛谷P4246 [SHOI2008]堵塞的交通(线段树分治+并查集)

    题面 Bzoj 洛谷 题解 考虑用并查集维护图的连通性,接着用线段树分治对每个修改进行分治. 具体来说,就是用一个时间轴表示图的状态,用线段树维护,对于一条边,我们判断如果他的存在时间正好在这个区间内 ...

  6. P4285 [SHOI2008]汉诺塔

    题目描述 汉诺塔由三根柱子(分别用A.B.C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形体. 对汉诺塔的一次合法的操作是指:从一根 ...

  7. 洛谷 P1242 新汉诺塔

    原题链接 题目描述 设有n个大小不等的中空圆盘,按从小到大的顺序从1到n编号.将这n个圆盘任意的迭套在三根立柱上,立柱的编号分别为A.B.C,这个状态称为初始状态. 现在要求找到一种步数最少的移动方案 ...

  8. 洛谷P1242 新汉诺塔

    传送门啦 首先要将第n个盘子从x到y,那么就要把比n小的盘子全部移到6-x-y,然后将n移到y 仔细想想:6代表的是3根初始柱,3根目标柱. 6-(x+y) 便是我们的中转柱了,因为到这个位置是最优的 ...

  9. 洛谷P1242 新汉诺塔 【神奇的递归】

    题目描述 设有n个大小不等的中空圆盘,按从小到大的顺序从1到n编号.将这n个圆盘任意的迭套在三根立柱上,立柱的编号分别为A.B.C,这个状态称为初始状态. 现在要求找到一种步数最少的移动方案,使得从初 ...

随机推荐

  1. iOS 混合开发之 Cordova 实践

    在15年时,之前公司使用 Cordova 做混合开发使用,后来公司没有用到了,现在重新记录下. Cordova (官网:http://cordova.apache.org/)简介: Apache Co ...

  2. 「CF197B Limit」

    题目撞名 题目大意: 给出两个函数 \(P(x),Q(x)\). \(P(x)=a_0 \times x^N+a_1 \times x^{N-1}+a_2 \times x^{N-2} \cdots ...

  3. 使用YUM安装软件时提示PackageKit睡眠中解决方法!

    报错如图所示: 解决方法一:移除var/run/yum.pid文件 方法二:直接杀掉进程号 报错的时候会跟进程号 直接利用kill   -9  +进程号

  4. Centos7虚拟环境virtualenv与virtualenvwrapper的安装及基本使用

    一.使用虚拟环境的原因 在使用 Python 开发的过程中,工程一多,难免会碰到不同的工程依赖不同版本的库的问题:亦或者是在开发过程中不想让物理环境里充斥各种各样的库,引发未来的依赖灾难.此时,我们需 ...

  5. C/C++网络编程6——实现基于UDP的服务器端/客户端

    通过前面几节的内容,我们已经可以实现基本的C/S结构的程序了,但是当多个客户端同时向服务器端请求服务时,服务器端只能按顺序一个一个的服务,这种情况下,客户端的用户是无法忍受的.所以虚实现并发的服务器端 ...

  6. python中的拷贝

    再说拷贝之前先说一说 is 与 == is 的作用是 比较两个引用是否为一个地址 == 是比较两个值 对变量 a  变量 b  都赋值为 2 : a 与 b 的值相等我们都可以理解,但是a与b引用地址 ...

  7. 关于java自学的内容以及感受(7.28)

    这一周学习了关于一些算法运算,我进行了程序的编写与运行,代码如下: public class TestSign{ public static void main(String[] args){ int ...

  8. nginx 的提升多个小文件访问的性能模块

    阿里开源的第三方模块下载地址:https://github.com/alibaba/nginx-http-concat 下载模块 git clone https://github.com/alibab ...

  9. C/C++ — CreateThread 相关 API

    使用互斥对象: #include <windows.h> #include <iostream> #define THREADCOUNT 6 HANDLE ghMutex; D ...

  10. ecshop代码分析一(init.php文件)

    ecshop代码分析一(init.php文件)   因为工作原因,需要对ecshop二次开发,顺便记录一下对ecshop源代码的一些分析: 首先是init.php文件,这个文件在ecshop每个页面都 ...