UVA 10254 - The Priest Mathematician (dp | 汉诺塔 | 找规律 | 大数)

时间:2023-02-26 19:04:29

本文出自   http://blog.csdn.net/shuangde800

题目点击打开链接

题意:

汉诺塔游戏请看 百度百科

正常的汉诺塔游戏是只有3个柱子,并且如果有n个圆盘,至少需要2^n-1步才能达到目标。

但是在这题中,有4根柱子,并且按照下面规则来玩:

1. 先把圆盘顶部前k个盘子全部搬到第四根柱子上,

2. 然后把剩下的n-k个盘子在前3根柱子中按照经典的规则搬到某个柱子上(假设是a柱),

3. 最后再把那k个盘子搬到目标a柱上。

问按照这样的规则,最少需要几步?

思路:

我们先设g[n]表示按照经典的游戏规则(3根柱子),n个盘子最少需要g[n]步,可以知道g[n] = 2^n-1

然后我们再设f[n]表示按照4根柱子的规则来,n个盘子最少需要f[n]步。

那么按照上面步骤可以推出:

1. 把圆盘顶部前k个盘子全部搬到第四根柱子 上 ==》 需要f[k]步

2. 把剩下的n-k个盘子在前3根柱子中按照经典的规则搬到某个柱子上 (假设是a柱) ==》需要g[n-k]步

3. 最后再把那k个盘子搬到目标a柱上 ==》需要f[k]步

所以,f[n] = f[k]*2+g[n-k]

因为f[n]要最小,且k不确定,所以枚举一下k,取最小值即可:

f[n]  =  min{ f[k]*2+g[n-k] , 1<=k<=n }

由于n过大,所以要用到大数。

由于本题的n为10000,上面的算法复杂度为O(n^2),所以不能用上面方法。

那么就打表找规律一下,并不难找

观察下面前20个,不难找出规律:

f[1] = 1
----------------
f[2] = 3, f[2] = f[1] + 2^1
f[3] = 5, f[3] = f[2] + 2^1
共 2 个 2^1
----------------
f[4] = 9, f[4] = f[3] + 2^2
f[5] = 13, f[5] = f[4] + 2^2
f[6] = 17, f[6] = f[5] + 2^2
共 3 个 2^2
----------------
f[7] = 25, f[7] = f[6] + 2^3
f[8] = 33, f[8] = f[7] + 2^3
f[9] = 41, f[9] = f[8] + 2^3
f[10] = 49, f[10] = f[9] + 2^3
共 4 个 2^3
----------------
f[11] = 65, f[11] = f[10] + 2^4
f[12] = 81, f[12] = f[11] + 2^4
f[13] = 97, f[13] = f[12] + 2^4
f[14] = 113, f[14] = f[13] + 2^4
f[15] = 129, f[15] = f[14] + 2^4
共 5 个 2^4
----------------
f[16] = 161, f[16] = f[15] + 2^5
f[17] = 193, f[17] = f[16] + 2^5
f[18] = 225, f[18] = f[17] + 2^5
f[19] = 257, f[19] = f[18] + 2^5
f[20] = 289, f[20] = f[19] + 2^5
共 6 个 2^5
----------------

代码:

/**===========================================
* This is a solution for ACM/ICPC problem.
*
* @author: shuangde
* @blog: http://blog.csdn.net/shuangde800
* @email: zengshuangde@gmail.com
*============================================*/ import java.math.*;
import java.util.Scanner; public class Main {
public static void main(String args[]){ BigInteger f[] = new BigInteger[10010];
f[0] = BigInteger.valueOf(0);
f[1] = BigInteger.valueOf(1);
int i = 2;
int k=1;
while(i <= 10000){
BigInteger add = BigInteger.valueOf(1).shiftLeft(k);
for(int j=0; j<k+1 && i<=10000; ++j){
f[i] = f[i-1].add(add);
++i;
}
++k;
}
Scanner cin = new Scanner(System.in);
while(cin.hasNext()){
int n = cin.nextInt();
System.out.println(f[n]);
}
}
}

UVA 10254 - The Priest Mathematician (dp | 汉诺塔 | 找规律 | 大数)的更多相关文章

  1. 递推&plus;高精度&plus;找规律 UVA 10254 The Priest Mathematician

    题目传送门 /* 题意:汉诺塔问题变形,多了第四个盘子可以放前k个塔,然后n-k个是经典的汉诺塔问题,问最少操作次数 递推+高精度+找规律:f[k]表示前k放在第四个盘子,g[n-k]表示经典三个盘子 ...

  2. UVA 10795 A Different Task(汉诺塔 递归&rpar;)

    A Different Task The (Three peg) Tower of Hanoi problem is a popular one in computer science. Briefl ...

  3. 汉诺塔III 汉诺塔IV 汉诺塔V &lpar;规律&rpar;

    汉诺塔III Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  4. BZOJ 1019&colon; &lbrack;SHOI2008&rsqb;汉诺塔&lpar; dp &rpar;

    dp(x, y)表示第x根柱子上y个盘子移开后到哪根柱子以及花费步数..然后根据汉诺塔原理去转移... ------------------------------------------------ ...

  5. &dollar;bzoj1019-SHOI2008&dollar; 汉诺塔 &dollar;dp&dollar;

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

  6. hdu 1207 汉诺塔II &lpar;DP&plus;递推&rpar;

    汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  7. 汉诺塔(思维、DP思想)

    链接:https://ac.nowcoder.com/acm/contest/3007/C来源:牛客网 题目描述 现在你有 N 块矩形木板,第 i 块木板的尺寸是 Xi*Yi,你想用这些木板来玩汉诺塔 ...

  8. BZOJ&lowbar;1019&lowbar;&lbrack;SHOI2008&rsqb;&lowbar;汉诺塔&lowbar;&lpar;DP&rpar;

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1019 汉诺塔游戏,但是有移动优先级,在不违反原有规则的情况下,给定优先移动目标.求完成游戏所需 ...

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

    [经典汉诺塔问题] 汉诺(Hanoi)塔问题:古代有一个梵塔,塔内有三个座A.B.C,A座上有64个盘子,盘子大小不等,大的在下,小的在上.有一个和尚想把这64个盘子从A座移到B座,但每次只能允许移动 ...

随机推荐

  1. c&plus;&plus;new&sol;delete---9

    原创博客:转载请标明出处:http://www.cnblogs.com/zxouxuewei/   C++new和delete实现原理 new 与delete是C++预定的操作符,它们一般需要配套使用 ...

  2. 【Qt】Qt之自定义搜索框【转】

    简述 关于搜索框,大家都经常接触.例如:浏览器搜索.Windows资源管理器搜索等. 当然,这些对于Qt实现来说毫无压力,只要思路清晰,分分钟搞定. 简述 效果 细节分析 Coding 源码下载 效果 ...

  3. 最简单的CRC32源码-逐BYTE法

    从按BIT计算转到按BYTE计算,要利用异或的一个性质,具体见前面的文章<再探CRC >. 其实方法跟逐BIT法是一样的,我们只是利用异或的性质,把数据分成一BYTE一BYTE来计算,一B ...

  4. CSS 背景图像 填充部分元素示例

    填充部分元素示例 为某个元素设置CSS规则background-image 属性,则可以做到部分元素有背景颜色. 下面的示例演示如何如何给段落元素加背景. <!DOCTYPE html> ...

  5. &lbrack;20181109&rsqb;12c sqlplus rowprefetch参数5

    [20181109]12c sqlplus rowprefetch参数5.txt --//这几天一直在探究设置sqlplus参数rowprefetch与arraysize的关系,有必要做一些总结以及一 ...

  6. InitializingBean和DisposableBean

    InitializingBean 记住一点:InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的子类,在初始化bea ...

  7. 配置ArcGIS Server使用LDAP身份认证

    1.登陆ArcGIS Server Manager,修改站点的安全设置.选择用户和角色来自现有企业系统(LDAP或Windows域). 2.选择LDAP存储类型. 3.填写LDAP用户存储连接信息.主 ...

  8. 全链路追踪traceId&comma;ThreadLocal与ExecutorService

    关于全链路追踪traceId遇到线程池的问题,做过架构的估计都遇到过,现在以写个demo,总体思想就是获取父线程traceId,给子线程,子线程用完移除掉. mac上的chrome时不时崩溃,写了一大 ...

  9. nginx 配置中的if判断

    正则表达式匹配:     ==:等值比较;     ~:与指定正则表达式模式匹配时返回“真”,判断匹配与否时区分字符大小写:     ~*:与指定正则表达式模式匹配时返回“真”,判断匹配与否时不区分字 ...

  10. java read读取方法 之 指定读取大小,根据返回值判断是否读取所有的内容 -1表示读取完毕

    当读取的内容小于指定的长度时候 字符数组里面会出现一部分字符是上一次遗留下来的情况