codefores 392B Tower of Hanoi (记忆搜索)

来源:互联网 发布:免费手机pdf编辑软件 编辑:程序博客网 时间:2024/05/22 05:17

题意:

和往常Hanoi问题不一样,这题给出每种操作的花费,用一个矩阵表示cost[i][j],表示从i号移动到j号的花费。问如何移动使得1中的全部圆块移动到3花费最小。

题解:

很明显要用记忆优化,那么正常的Hanoi问题移动的递归是这样的  dfs(l,n-1,x),move(l,r),dfs(x,n-1,r)

但是这题要求得最小花费决策肯定不止这一个,其实还可以这样 dfs(l,n-1,r),move(l,x),dfs(r,n-1,l),

move(x,r),dfs(l,n-1,r) 。其实就这两方案可以放,那么很显然状态方程就出来了。

dp[l][n][r] = max{ dfs(l,n-1,r)+cost[l][r] , dfs(l,n-1,r)*2+dfs(r,n-1,l)+cost[l][x]+cost[x][r] }

注意一点,当只有一个方块移动时,要判断cost[l][r],cost[l][x]+cost[x][r]那个更小。


#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<map>using namespace std;typedef long long ll;const int oo=0x3f3f3f3f;const ll OO=1LL<<61;const ll MOD=2147483647;const int maxn=5005;ll dp[4][45][4];int cost[4][4];ll Hanoi(int l,int n,int r){    if(dp[l][n][r]!=-1)return dp[l][n][r];    int x=6-l-r;    if(n==1)        return dp[l][n][r]=min(cost[l][r],cost[l][x]+cost[x][r]);    ll ans1=Hanoi(l,n-1,x)+Hanoi(x,n-1,r)+cost[l][r];    ll ans2=Hanoi(l,n-1,r)*2+Hanoi(r,n-1,l)+cost[l][x]+cost[x][r];    return dp[l][n][r]=min(ans1,ans2);}int main(){    int n;    memset(dp,-1,sizeof dp);    for(int i=1;i<=3;i++)        for(int j=1;j<=3;j++)            scanf("%d",&cost[i][j]);    scanf("%d",&n);    cout<<Hanoi(1,n,3)<<endl;    return 0;}/**0 2 21 0 1001 2 03*/



0 0
原创粉丝点击