[DP]vijos1139小胖办证
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[DP]vijos1139小胖办证相关的知识,希望对你有一定的参考价值。
题目梗概
m层楼,每层楼n个办事员,办事员只有在以下三种情况任意满足一种的情况下才会帮你办证。并且每次办事会花费一定费用
1.办事员在一楼
2. 办事员左边的人或者右边的人帮你办证了。
3.办事情员楼下的人帮你办证了。
思考
方程不难推dp[i][j]表示前i层前m个办事员的最小花费.
dp[i][j] 从dp[i-1][j] dp[i][j-1] dp[i][j+1]三个方程转移 需要注意的问题是第一层要特殊处理。
输出的之后递归找(数据还可以)
#include <cstdio> #include <algorithm> #include <cstring> using std::max; using std::min; int n,m,map[105][505],dp[105][505],End,Min=(1<<30)-1; void print(int x,int y){ if(x==1) { printf("%d\n",y); return ; } if(dp[x-1][y]+map[x][y]==dp[x][y]) print(x-1,y); else if(dp[x][y-1]+map[x][y]==dp[x][y]) print(x,y-1); else print(x,y+1); printf("%d\n",y); } int main(){ memset(dp,0x3f3f3f3f,sizeof(dp)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&map[i][j]); for(int i=1;i<=m;i++) dp[1][i]=map[1][i]; for(int i=2;i<=n;i++){ for(int j=1;j<=m;j++) dp[i][j]=dp[i-1][j]+map[i][j]; for(int j=2;j<=m;j++) dp[i][j]=min(dp[i][j],dp[i][j-1]+map[i][j]); for(int j=m-1;j>=1;j--) dp[i][j]=min(dp[i][j],dp[i][j+1]+map[i][j]); } for(int i=1;i<=m;i++){ if(dp[n][i]<Min){ Min = dp[n][i]; End=i; } } //printf("%d\n",End); print(n,End); return 0; }
以上是关于[DP]vijos1139小胖办证的主要内容,如果未能解决你的问题,请参考以下文章