【题解】洛谷P1002过河卒

首先,一道入门DP

然而对于蒟蒻的我已经难到爆了好吗


第一点:动态转移方程

用DP的关键

这题我们可以发现每一步的方案数由上面的那步加上左边的那步得到

所以自然而然的方程就出来了:

f[i][k]=f[i-1][k]+f[i][k-1]


第二点:DP边界

在所有的方案数计算内我们可以快速准确地发现:f[0][0]=1

走到起点的方案数为一种


注意事项

本题有个较为坑爹的地方:

马可以在起点

所以需要特判,在代码环节会提到


那么代码就来了

    #include<iostream>
    using namespace std;
    long long f[25][25];//不用高精,但要long long 
    int dx[8]={1,1,-1,-1,2,2,-2,-2},
        dy[8]={2,-2,2,-2,1,-1,1,-1};//马可以走到的地方 
    int n,m,x,y;
    int main()
    {
        cin>>n>>m>>x>>y;
        f[x][y]=-1;//定义马的那格不能走 
        for(int i=0;i<8;i++)
        {
            int xx=x+dx[i];
            int yy=y+dy[i];
            if(xx>=0&&xx<=n&&yy>=0&&yy<=m)
            f[xx][yy]=-1;
        }//定义马可以走到的格子不能走
        if(f[0][0]!=-1)//判断起点有没有被马占领 
        {
            f[0][0]=1;//定义走到起点的方法有一种,DP的边界 
            for(int i=0;i<=n;i++)
            for(int j=0;j<=m;j++)
            if(f[i][j]!=-1)//如果当前的格子能走的话,计算从起点到这里的方法数  
            {
                if(i>=1&&f[i-1][j]!=-1)//i>=1是为了避免i=0的情况
                f[i][j]+=f[i-1][j];
                if(j>=1&&f[i][j-1]!=-1)//同理 
                f[i][j]+=f[i][j-1];
            }
            cout<<f[n][m];//输出到终点的方法数 
        }
        else//如果有,自然而然的是没办法走到终点 
        cout<<0;
    }

大功告成!
蒟蒻的第一个题解庆祝!

posted @ 2018-07-08 11:31  Nanchtiy  阅读(451)  评论(0编辑  收藏  举报