1. 程式人生 > >漢諾塔 + 一道簡單貪心題

漢諾塔 + 一道簡單貪心題

漢諾塔

移動n層塔至少需要多少次

1層 1次

2層 3次

3層 7次

4層 15次

.

.

.

.

沒錯,就是2n+1的規律

int han(int n)
{
   if(n==1)
        return 1;
   else
        return 2*han(n-1)+1;
}

3層漢諾塔GIF

3層漢諾塔GIF

出來混遲早要還的o(╯□╰)o

漢諾塔的變形  ----總共有n層移動完成後,求特定第k層塔至少需要移動多少次?

用1,2,...,n表示n個盤子,稱為1號盤,2號盤,...。號數大盤子就大。經典的漢諾塔問 
題經常作為一個遞迴的經典例題存在。可能有人並不知道漢諾塔問題的典故。漢諾塔來源於 
印度傳說的一個故事,上帝創造世界時作了三根金剛石柱子,在一根柱子上從下往上按大小 
順序摞著64片黃金圓盤。上帝命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱 
子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一回只能移動一個圓盤。我們 
知道最少需要移動2^64-1次.在移動過程中發現,有的圓盤移動次數多,有的少 。 告之盤 
子總數和盤號,計算該盤子的移動次數.

Input

包含多組資料,首先輸入T,表示有T組資料.每個資料一行,是盤子的數目N(1<=N<=60)和盤 
號k(1<=k<=N)。 

Output

對於每組資料,輸出一個數,到達目標時k號盤需要的最少移動數。 

Sample Input

2
60 1
3 1

Sample Output

576460752303423488
4

[解析]

首先我要知道,k 號盤子的移動次數只與 k 下面的盤子數有關,而與 k 上面的盤子數無關

就像三個盤子一樣,如果想要將第三個盤子移到C柱子只需要一步,
 但是前提是將上邊2個盤子通過C柱子移到B柱, 而這一過程中移動第二盤子
時會在第三個盤子的基礎上移動次數多1倍, 同理, 第一個盤子也會比第二個盤子移動次數多1倍。
所以當有n個盤時,第n-1個盤子的移動次數
總是第n個盤移動次數多1倍,即cishu(n-1) = 2*cishu(n).  
當求n個盤中的第k個盤子的移動次數就可以轉化為(n-k)個盤子到n的移動次數, 這時
第k個盤就相當於(n-k)個盤中的第一個盤子

有圖有真相,3層漢諾塔總共需要移動7次,每一層的移動次數確實也有規律,就是2倍的規律

#include<stdio.h>
long long  f(int n,int m)
{
    if(n==m)
        return 1;
    else
        return  2*f(n,m+1);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,k;
        scanf("%d%d",&n,&k);

        printf("%lld\n",f(n,k));
    }
    return 0;
}

一道貪心題

FatMouse' Trade

肥鼠準備了 M 磅的貓糧,準備和看管倉庫的貓交易,倉庫裡裝有他最喜愛的食物 Java 豆。

倉庫有 N 個房間。第 i 間房包含了 J[i] 磅的 Java 豆,需要 F[i] 磅的貓糧。肥鼠不必為了房間中的所有 Java 豆而交易,相反,他可以支付 F[i] * a% 磅的貓糧去交換得到 J[i] * a% 磅的 Java 豆。這裡,a 表示一個實數。

現在他將這項任務分配給了你:請告訴他,能夠獲得的 Java 豆的最大值是多少。

輸入

輸入包含多組測試資料。

對於每組測試資料,以包含了兩個非負整數 M 和 N 的一行開始。接下來的 N 行,每行相應包含了兩個非負整數 J[i] 和 F[i]。

最後一組測試資料是兩個 -1。所有的整數均不超過 1000。

輸出

對於每組測試資料,在單獨的一行中列印一個實數,精確到小數點後 3 位數,表示肥鼠能夠取得的 Java 豆的最大值。

示例輸入

5 3
7 2
4 3
5 2
20 3
25 18
24 15
15 10
-1 -1

示例輸出

13.333
31.500

#include<bits/stdc++.h>
using namespace std;
struct node
{
    double j,f,p;
}st[1000];
int cmp(node x,node y)
{
    return x.p>y.p;
}
int main()
{
    int m,n;
    while(cin>>m>>n&&(n!=-1||m!=-1)){//貓糧有m磅 房間有n個
        double sum=0;//一定要是double  int不行
        int j;
        for(int i=0;i<n;i++){
           cin>>st[i].j>>st[i].f;
            st[i].p=st[i].j/st[i].f;//單位貓糧能換的Java豆為p
        }
        sort(st,st+n,cmp);//按(價效比)st[i].p從大到小排序
        for(int i=0;i<n;i++){
            if(m>=st[i].f){//如果所剩貓糧 >= i房間需要的貓糧
                sum+=st[i].j;//得到i房間的Java豆
                m-=st[i].f;//減去i房間需要的貓糧
            }
            else{
                sum+=st[i].p * m;
                break;
            }
        }
        printf("%.3lf\n",sum);
    }
    return 0;
}

相關推薦

+ 一道簡單貪心

漢諾塔 移動n層塔至少需要多少次 1層 1次 2層 3次 3層 7次 4層 15次 . . . . 沒錯,就是2n+1的規律 int han(int n) { if(n==1) return 1; else r

hdu1207 II 簡單dp

題意:漢諾塔,多了一根柱子,問你尋找最快的移動次數。 dp [ n ] = dp [ n - j ] * 2 + pow( 2, j ) - 1; 就是把j個漢諾塔移到一根上dp[ n - j ]

HDU1996 VI【水

漢諾塔VI Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3193    Accepted Submissi

遊戲簡單玩法

今天學習遞迴的時候,書上以一款名叫<漢諾塔>的解謎遊戲為例。雖然開始被那演算法搞蒙了,不過我倒是把這遊戲的玩法給解出來了,這裡分享一下. 遊戲簡介: 遊戲裡有三根金剛石柱子,左邊的柱子上從下往上按照大小順序摞著N片黃金圓盤。玩家需要做的是把圓盤從下面開始按

hdu 2064 III (水

漢諾塔III Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su

每天一道演算法——

漢諾塔如圖所示,把圓盤從下面開始按大小順序重新擺放在另一根柱子上,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。 它的解法可以採用分解法,把一個大的問題,逐步分解成一個個小問題。比如我們想把A中的盤子挪到B上,可以把問題分解成,將A的前n-1個盤子先挪到C,然

nyoj 1078 (四)[二分圖 || 規律 || 暴力 || 貪心]

二分圖 二分圖匹配 int 處理 names 特殊 mes while 最小路徑覆蓋 題目:nyoj 1078 漢諾塔(四) 分析:做這個題目的時候是在圖論的題目裏面看到的。到時讀了題目推了一下,發現好像有點規律。試了一下果然過了。 後來看了一下數據,才50。那

python寫簡單的圖形界面解題器

color 一個 let 參考 span tkinter try import count 下圖是漢諾塔遊戲的簡單圖示,我們要把x柱子上面的移動到z軸上面(漢諾塔遊戲規則可以自行搜索,這裏不做介紹) 需要引入tkinter和ScrolledText模塊,下面直接貼代碼(我

問題其實很簡單

推出 class 回溯思想 除了 source 問題 容易 假設 為我 首先上代碼 1 def hanoi_move(n, source, dest, intermediate): 2 if n >= 1: # 遞歸出口,只剩一個盤子 3

簡單問題【遞迴】

題目連結:http://bailian.openjudge.cn/practice/4147/ 問題描述: 有三根杆子A,B,C。A杆上有N個(N>1)穿孔圓盤,盤的尺寸由下到上依次變小。要求按下列規則將所有圓盤移至C杆: 每次只能移動一個圓盤; 大盤不能疊在小盤上面。 提示:可將圓盤

簡單全面分析問題!!!!

初學者分析漢諾塔問題,更通俗的講就是圓盤移動,其實只要簡單將任意個圓盤分解為兩個總體移動就好!!!! (簡單通俗易懂,希望能得到大家的支援能幫到大家,也希望能有人能一起討論c++問題,我是學c++的,我也只是個初學者!!!!) 分析來看**a**是目標所在

的改編(用棧求解,分別遞迴和非遞迴)

限制不能從最左側的塔直接移動到最右側,也不能從最右側直接移動到最左側,而是必須經過中間,求當塔有N層的時候,列印最優移動過程和最優移動總步數 例如:當塔為兩層時,最上層的塔記為1,最下層的塔記為2,則

簡單演算法解決問題

漢諾塔:漢諾塔(又稱河內塔)問題是源於印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三

python實現簡單問題

漢諾塔問題可以簡單描述成為將a柱子上的圓盤按一定規則藉助b柱子完美地複製到c柱子上。現假設有a,b,c三根柱子,a柱子上的圓盤從上到下依次標號為1,2,3,……,n,且為遞增狀態。規則:每次移動一個盤子,且只能讓小的放在大的上面。目標:移動到c柱子上,與原來a上

遞迴

看動圖:https://www.cnblogs.com/tgycoder/p/6063722.html 源:a,  目標: b aux: c   public class HiValen { public static void main(String

""演算法-之通俗易懂,簡單的原理-java程式設計

1.初步介紹 很多朋友向我諮詢漢諾塔的執行過程和原理,其實對於漢諾塔問題,如果不採用遞迴演算法,這種問題就會難以解答,那麼下面我通過圖解和程式碼統一把過程和原理寫出來,並講解一些技巧,希望能幫組

簡單圖形設計思想1(C)

我們都知道漢諾塔遊戲,在C語言程式設計中,我們也可以簡單的設計出它的圖形,但是如何動態設計初始化漢諾塔的層數呢?這看起來有點棘手,但是隻要觀察其中的規律就可以用for迴圈語句的巢狀和if...else語句的巢狀設計出,至於更復雜的填充顏色這裡就不說了,只以學習其中的一些演算

簡單 簡單的遞迴(杭電oj2064 2077)

約19世紀末,在歐州的商店中出售一種智力玩具,在一塊銅板上有三根杆,最左邊的杆上自上而下、由小到大順序串著由64個圓盤構成的塔。目的是將最左邊杆上的盤全部移到右邊的杆上,條件是一次只能移動一個盤,且不允許大盤放在小盤的上面。 現在我們改變遊戲的玩法,不允許直接從最左(右)邊移到最右(左)邊(每次移動一定是

[Python]小甲魚Python視頻第023~024課(遞歸:這幫小兔崽子、)課後及參考解答

列表 使用遞歸 admin odi res urn 問題 文字 n-1 # -*- coding: utf-8 -*- """ Created on Thu Mar 7 19:44:16 2019 @author: Administrator """

移動

pri -- nbsp else == move 漢諾塔 int bsp 學習python進行中: def move(n, a, b, c): if n ==1: print a,‘-->‘,c else: move(n-1,a,c