codeforces div2 round#230 D

算是经典模型和比较简单的一道dp吧,比赛完之后看到题目我这种dp渣都有点感动。

我们用dp[i][j][k]来表示将i个盘子从j号柱子移到k号柱子的最小花费,那么最终我们所求的就是dp[n][1][3]。

状态转移方程也比较好想,dp[n][a][c]=min(dp[n-1][a][b]+cost[a][c]+dp[n-1][b][c],dp[n-1][a][c]+cost[a][b]+dp[n-1][c][a]+cost[b][c]+dp[n-1][a][c])。

对dp的理解不是很在行,所以dp还是习惯拿记忆化搜索写。

#include "cstdio"
#include "cstring"
#include "algorithm"
#define LL long long
using namespace std;

LL cost[4][4];
LL dp[50][4][4];

LL dfs(int n,int a,int c){
    if(n==0)  return dp[n][a][c]=0;
    if(dp[n][a][c]!=-1)  return dp[n][a][c];
    LL ans,tmp;
    int b=6-a-c;
    ans=dfs(n-1,a,b)+cost[a][c]+dfs(n-1,b,c);
    tmp=2*dfs(n-1,a,c)+cost[a][b]+dfs(n-1,c,a)+cost[b][c];
    ans=min(ans,tmp);
    return dp[n][a][c]=ans;
}

int main(){
    int n;
    for(int i=1;i<4;i++)
        for(int j=1;j<4;j++)  scanf("%lld",&cost[i][j]);
    scanf("%d",&n);
    for(int i=0;i<=n;i++)
        for(int j=1;j<4;j++)
            for(int k=1;k<4;k++)  dp[i][j][k]=-1;
    printf("%lld\n",dfs(n,1,3));
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值