洛谷P1002 过河卒

题目就不介绍了,自己找找就行了,应该比较容易找到。

看到A点和B点的坐标范围就可以求出数组的行列范围了(用来存储每一个点到达点B的路径数);为防止马的拦截点跑出去,需要将出发点A(0,0)转化为数组中的(1,1),这个时候要稍微调整遍历范围,记得要开到23格。由于数据可能较大,数组类型用long long(亲测有效)。 因为卒的移动只能是向下一格或者向右一格,所有要到达B(n,m),就必须要到达(n-1,m)或(n,m-1),而到达这两个点的路径数也同样可以这样一直类推下去。 其状态转移方程为f(n,m)=f(n-1,m)+f(n,m-1) 然后将路径数记忆化。 最后直接输出就行

#include
using namespace std;
long long a[23][23];//int型会溢出
 int main()
 {
    for(int i=0;i<23;i++)
        for(int j=0;j<23;j++)
    a[i][j]=1;
  //本来只需要初始第n+1行和m+1列的(都处于边界,只有一种走法),但是我突然忘了怎么弄,就全部初始化为1了。由于在后面的求解过程中我是直接求和的,会覆盖原来的1,所以也能得到正解。
    int n,m;
    int c,b;//分别为行和列 
     cin>>c>>b;//B点的坐标 
    cin>>n>>m;//马的坐标 
 n++,m++;//出发点发生变化,需要调整B的坐标 
    a[n][m]=a[n+1][m-2]=a[n+2][m-1]=a[n+1][m+2]=a[n+2][m+1]=a[n-1][m-2]=a[n-2][m-1]=a[n-2][m+1]=a[n-1][m+2]=0;
    //初始化拦截点 
    for(int i=b;i>=1;--i)/*b,c都不需要-1,原因和B一样 */
        {
        for(int j=c;j>=1;--j)
            {
             if(a[j][i]) a[j][i]=a[j][i+1]+a[j+1][i];//判断是否可以走
             }
        }
  /*由于我是倒着来的,即由终点到起点,所以这个部分和其他几个大佬不一样,但是原理完全相同。*/
    cout<

你可能感兴趣的:(洛谷P1002 过河卒)