BOJ1293 小马过河 dp

时间:2021-03-27 04:07:46

题意:给一个矩阵。从上到下一样,(题目里说的是从下到上,但是其实一样)代码里面就是从上到下考虑。

每一行到下一行都只有三个选择,左下,下,右下。

所以转移方程为:

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();
    }
}