codeforces div2 round#230 D

来源:互联网 发布:网络照片素材 编辑:程序博客网 时间:2024/05/01 04:12

算是经典模型和比较简单的一道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 longusing 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