CF 392 B. Tower of Hanoi 记忆化搜索

     比赛时候完全想不明白该怎么做,刚刚看了大神“码年大吉”的题解原题解报告,顿时想明白,好开心

题意:

     还是汉诺塔的规则,要求1,3根柱子,2,大盘子不能放在小盘子上。不同的是给了一3*3矩阵,cost[i][j] 代表从第i根到第j跟需要的花费。问n个盘子,从1号柱子搬到3号柱子的最小花费。

还是递归的思想。搬第 x个盘子时,需要考虑 上面的x-1个盘子移动的方式。

  第一种

  CF 392 B. Tower of Hanoi 记忆化搜索_第1张图片

第二种:

CF 392 B. Tower of Hanoi 记忆化搜索_第2张图片

#include
#include
#include
#include
#include
#include
#include
using namespace std;
long long cost[4][4];
long long best[4][4];
bool  vis[4][4][44];
long long dp[4][4][44];
long long dfs(int st ,int ed,int n)
{
    if(vis[st][ed][n]) return dp[st][ed][n];
    vis[st][ed][n]=1;
    int x=6-st-ed;
    if(n==1) return dp[st][ed][n]=best[st][ed];
    long long tp1=dfs(st,x,n-1)+dfs(x,ed,n-1) +cost[st][ed];
    long long tp2=dfs(st,ed,n-1)*2+ dfs(ed,st,n-1)+cost[st][x]+cost[x][ed];
    return dp[st][ed][n]=min(tp1,tp2);

}
int main()
{
 //freopen("in.txt","r",stdin);
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=3;i++)
     for(int j=1;j<=3;j++)
       {
           cin>>cost[i][j];
           best[i][j]=cost[i][j];
       }
    for(int i=1;i<=3;i++)
    {
        for(int j=1;j<=3;j++)
         {
             if(i==j) continue;
             int x=6-i-j;
             best[i][j]=min(best[i][j],best[i][x]+best[x][j]);
         }
    }
    int all;
    scanf("%d",&all);
    long long ans=dfs(1,3,all);
    cout<


你可能感兴趣的:(CF题解报告)