BNU 34978 汉诺塔 求期望步数

题目链接:点击打开链接

我们用dp[i]表示 随机i个盘子时,恢复原位需要的步数的期望

f[i]表示i个盘子下普通的汉诺塔玩法的步数

既然是随机,那么我们就认为是在上一次随机的情况下,

把第n个放到任意一根柱子的底部

那么若随机放到了第3个柱子,则步数就是dp[n-1]

若放到了第1根柱子,则先把前面的n-1个盘子移动到第2根柱子上,花费是dp[n-1]

然后再把n盘子移动到第三根柱子,再把其他盘子移动到第三根柱子, 花费是 1+f[n-1]

就是这样_(:зゝ∠)_

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <vector>
#include <cmath>
using namespace std;
#define N 100
#define ll long long
ll n;
double f[N];
double dp[N];
int main() {
    f[1] = 1.0;
    for(int i = 2; i < N; i++) f[i] = f[i-1]*2.0+1.0;
    dp[1] = 0.666666666666666;
    for(int i = 2; i < N; i++)
        dp[i] = dp[i-1]/3.0 + 2.0 * (dp[i-1] + f[i-1] +1.0) / 3.0;
    int T, j;scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&j);
        printf("%.2f\n", dp[j]);
    }
    return 0;
}

BNU 34978 汉诺塔 求期望步数,布布扣,bubuko.com

时间: 2024-11-03 03:24:32

BNU 34978 汉诺塔 求期望步数的相关文章

BNUOJ 34978 汉诺塔

题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=34978 比赛还剩不到2分钟的时候想到了解法,写好代码提交时卡了一下,出AC结果时比赛已经结束了25秒,当时真的特别无语. 不解释别的. #include<iostream> #include<stdio.h> #include<math.h> #include<string.h> #include<algorithm> #include&

BNUOJ 34978 汉诺塔 (概率dp)

题目分析:对于 i 个盘 , 须要移动多少步,取决于最大的盘子在哪个杆上.在C杆上,则最大的盘不须要移动,由于初始状态一定是满足盘由下到上盘子依次变小的,仅仅须要移动i - 1个盘.假设在A杆上,则首先须要将最大盘移到C杆上.在此之前当然须要将其它i - 1个盘都移到B上,然后,将最大的盘移动到C上.然后移动i - 1个在B上的盘.假设最大的盘在B杆上,则相似于在A杆上的情况. 假设x个盘都在1个杆上 , 要移动到另外一个杆上,须要pow(2 . x) - 1步. 设dp[ i ] ?为要移动

【汉诺塔问题】UVa 10795 - A Different Task

[经典汉诺塔问题] 汉诺(Hanoi)塔问题:古代有一个梵塔,塔内有三个座A.B.C,A座上有64个盘子,盘子大小不等,大的在下,小的在上.有一个和尚想把这64个盘子从A座移到B座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上.在移动过程中可以利用B座,要求打印移动的步骤.如果只有一个盘子,则不需要利用B座,直接将盘子从A移动到C. 如果有2个盘子,可以先将盘子1上的盘子2移动到B:将盘子1移动到c:将盘子2移动到c.这说明了:可以借助B将2个盘子从A移

HDOJ-2175 汉诺塔IX

题目大意:基于汉诺塔原型,第一根柱子上有n个盘子,从上至下编号从1依次递增至n.在最佳移动方案中,第m次所移动的盘子的编号. 解题思路:模拟必然是会超时的.但根据汉诺塔的递归原理,容易发现,对于n阶汉诺塔,将第一个盘从A柱移动到B柱是一步,将前两个盘从A柱移动到B柱是3步,以此类推,将n个盘从A柱移动到B柱的步数是2^n-1步.而第m步必然在以上递推的值所划分出来的区间之中.查找到区间i后,可以发现,我们把问题缩小为求n-i阶汉诺塔的第m-(used[i]+1)步.同时,如果发现第m步正好是i阶

C#递归解决汉诺塔问题(Hanoi)

using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace MyExample_Hanoi_{    class Program    {        static void Main(string[] args)        {            HanoiCalculator c = new HanoiCalculator();            Cons

汉诺塔算法之求解最佳步数

写的不好,但是请尊重版权,转载请注明出处: http://www.cnblogs.com/xiaovw/ 何为汉诺塔? 答:汉诺塔是根据一个传说形成的一个问题.汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上.并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘. 关于汉诺塔的经典问题: 有三根相邻的柱子,标号为A,

递归求汉诺塔的解

递归求汉诺塔的解 // 递归求汉诺塔的解.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<stdio.h> #include<conio.h> #include<windows.h> void HanoiTower(int,char,char,char); void main() { int n; char A='A',B='B',C='C'; printf("---Hanoi To

汉诺塔问题与求子集

汉诺塔:从左到右有A.B.C三根柱子,其中A柱子上面有从小叠到大的n个圆盘,现要求将A柱子上的圆盘移到C柱子上去,期间只有一个原则:一次只能移到一个盘子且大盘子不能在小盘子上面,求移动的步骤.思路:当只有一个盘子时,直接将盘子从左移到右;当有n个盘子时,将n-1个盘子借助右柱从左柱移到中柱,然后将第n个盘子从左柱移到右柱,最后将n-1个盘子借助左柱从中柱移到右柱. public class Hannuota { public static void f(int n, String from, S

3145 汉诺塔游戏——http://codevs.cn/problem/3145/

第一部分:题目 题目描述 Description 汉诺塔问题(又称为河内塔问题),是一个大家熟知的问题.在A,B,C三根柱子上,有n个不同大小的圆盘(假设半径分别为1-n吧),一开始他们都叠在我A上(如图所示),你的目标是在最少的合法移动步数内将所有盘子从A塔移动到C塔. 游戏中的每一步规则如下: 1. 每一步只允许移动一个盘子(从一根柱子最上方到另一个柱子的最上方) 2. 移动的过程中,你必须保证大的盘子不能在小的盘子上方(小的可以放在大的上面,最大盘子下面不能有任何其他大小的盘子) 如对于n