技巧:
    递归 + 记忆化搜索
思路:
    基于统计的想法出发(可以打破移动顺序),一共有6中移动方式。 用一个长度为6的数组统计每一个位置需要操作的次数。最后合并求得总答案。
    用数组位置模拟统计的办法主要是为了方便记忆化搜索cache统计和递归函数逻辑闭环。
实现:
package main

import (
    . "fmt"
    "os"
    "io"
    "bufio"
)
//  0  1  2  3  4  5
// AB AC BA BC CA CB
func getOptIndex(cmd string) int {
    switch cmd {
        case "AB":
        return 0
        case "AC":
        return 1
        case "BA":
        return 2
        case "BC":
        return 3
        case "CA":
        return 4
        case "CB":
        return 5
    }
    return -1
}
// https://ac.nowcoder.com/acm/problem/201839
func NC201839(_r io.Reader, _w io.Writer) {
    in, out := bufio.NewReader(_r), bufio.NewWriter(_w)
    defer out.Flush()
    var n int
    Fscan(in, &n)
    
    cacheMap := make(map[string][6]int)
    
    var hanoi func(int, string, string, string)  [6]int
    hanoi = func(n int, a,b,c string) [6]int{
        if v, ok := cacheMap[Sprintf("%d%s%s%s",n,a,b,c)]; ok {
            return v
        }
        
        optCmd := [6]int{}
        if n == 1 {
            optCmd[getOptIndex(a + c)] += 1
            return optCmd
        }
        a2b := hanoi(n - 1, a, c, b)
        b2a := hanoi(n - 1, b, a, c)
         // merge
        for i := 0; i < 6; i++ {
            optCmd[i] +=a2b[i]
            optCmd[i] +=b2a[i]
        }
        // a2c
        optCmd[getOptIndex(a + c)] += 1
        cacheMap[Sprintf("%d%s%s%s",n,a,b,c)] = optCmd
        return optCmd
    }
   
    optArray := hanoi(n, "A","B","C")
    Fprintf(out, "%s->%s:%d\n", "A","B",optArray[0])
    Fprintf(out, "%s->%s:%d\n", "A","C",optArray[1])
    Fprintf(out, "%s->%s:%d\n", "B","A",optArray[2])
    Fprintf(out, "%s->%s:%d\n", "B","C",optArray[3])
    Fprintf(out, "%s->%s:%d\n", "C","A",optArray[4])
    Fprintf(out, "%s->%s:%d\n", "C","B",optArray[5])
    Fprintf(out, "SUM:%d\n", optArray[0]+optArray[1]+optArray[2]+optArray[3]+optArray[4]+optArray[5])
    
}
func main() {
    NC201839(os.Stdin, os.Stdout)
}