UVA 10254 – The Priest Mathematician (dp | 漢諾塔 | 找規律 | 大數)

來源:互聯網
上載者:User

本文出自   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^1f[3] = 5,  f[3] = f[2] + 2^1共 2 個 2^1----------------f[4] = 9,  f[4] = f[3] + 2^2f[5] = 13,  f[5] = f[4] + 2^2f[6] = 17,  f[6] = f[5] + 2^2共 3 個 2^2----------------f[7] = 25,  f[7] = f[6] + 2^3f[8] = 33,  f[8] = f[7] + 2^3f[9] = 41,  f[9] = f[8] + 2^3f[10] = 49,  f[10] = f[9] + 2^3共 4 個 2^3----------------f[11] = 65,  f[11] = f[10] + 2^4f[12] = 81,  f[12] = f[11] + 2^4f[13] = 97,  f[13] = f[12] + 2^4f[14] = 113,  f[14] = f[13] + 2^4f[15] = 129,  f[15] = f[14] + 2^4共 5 個 2^4----------------f[16] = 161,  f[16] = f[15] + 2^5f[17] = 193,  f[17] = f[16] + 2^5f[18] = 225,  f[18] = f[17] + 2^5f[19] = 257,  f[19] = f[18] + 2^5f[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]); }}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.