算是经典模型和比较简单的一道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; }
codeforces div2 round#230 D
最新推荐文章于 2022-11-22 23:15:14 发布