题意:给一个矩阵。从上到下一样,(题目里说的是从下到上,但是其实一样)代码里面就是从上到下考虑。
每一行到下一行都只有三个选择,左下,下,右下。
所以转移方程为:
dp[i][j]=min(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1])+w[i][j];
因为dp还很不熟练。
刚看到题目的时候其实第一反应是类似广搜的去模拟一下差不多,反正每一格只会影响下一行的三格。
然后写的时候就注意到了其实就是dp。
#include<iostream> #define min(a,b) (a<b?a:b) using namespace std; const int N=1005; int n,m; int mat[N][N]; unsigned int dp[N][N]; void bfs(int ii,int jj) { for(int j=jj-1;j<=jj+1;j++) { if(j>=1&&j<=m) { dp[ii+1][j]=min(dp[ii][jj]+mat[ii+1][j],dp[ii+1][j]); } } } void solve() { memset(dp,-1,sizeof(dp)); for(int j=1;j<=m;j++) dp[1][j]=mat[1][j]; for(int i=1;i<=n-1;i++) for(int j=1;j<=m;j++) bfs(i,j); int ans=(1<<30); for(int j=1;j<=m;j++) ans=min(dp[n][j],ans); printf("%d\n",ans); } int main() { while(scanf("%d%d",&n,&m),n!=0||m!=0) { memset(mat,0,sizeof(mat)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%d",&mat[i][j]); } solve(); } }