洛谷 1002 过河卒

洛谷 1002 过河卒

虽然这道题目的标签上有高精,但是用long long int就能AC

看到普及-的难度,本蒟蒻二话不说写了DFS,结果...只拿了40分,只好改变思路写了递推(个人认为DP!=递推)。

(DFS代码未AC,无注释)

#include<bits/stdc++.h>
using namespace std;
int mx,my,ex,ey;
bool v[25][25];
long long ans=0;
void dfs(int x,int y)
{
    if(x==ex&&y==ey) ans++;
    if(x>ex || y>ey) return;
    if(v[x+1][y]==0 && x+1<=ex) dfs(x+1,y);
    if(v[x][y+1]==0 && y+1<=ey) dfs(x,y+1);
    return;
}
int main()
{
    memset(v,0,sizeof(0));
    scanf("%d%d%d%d",&ex,&ey,&mx,&my);
    v[mx][my]=1;
    v[mx-1][my-2]=1;v[mx+2][my+1]=1;v[mx+1][my+2]=1;v[mx-2][my+1]=1;
    v[mx-1][my+2]=1;v[mx+2][my-1]=1;v[mx+1][my-2]=1;v[mx-2][my-1]=1;
    dfs(0,0);
    printf("%lld",ans);
    return 0;
} 

下为AC代码(递推)

由于卒只能向下向右移动,不难得出递推式 f [ i ] [ j ] = f [ i - 1 ] [ j ] + f [ i ] [ j - 1 ] (f [ i ] [ j ]为 起点到点(i,j)的路径数),马的控制区设为0,直接跳过即可。

这里为了防止数组下标为负数,将整个棋盘向右下移动(起点由(0,0)变为(1,1))。

#include<bits/stdc++.h> //万能库
using namespace std;
long long f[25][25];  //f[i][j]为 起点到点(i,j)的路径数
int n,m,hx,hy;
bool v[25][25];  //v数组记录点(i,j)是否为马的控制区
int main()
{
    scanf("%d%d%d%d",&n,&m,&hx,&hy);
    n+=1,m+=1,hx+=1,hy+=1; //整体移动,防止负数
    f[0][1]=1; //当循环到点(1,1)时,f[1][1]会被计算为1
    v[hx][hy]=1; //标记马的控制区
    v[hx-1][hy-2]=1;v[hx+2][hy+1]=1;v[hx+1][hy+2]=1;v[hx-2][hy+1]=1;
    v[hx-1][hy+2]=1;v[hx+2][hy-1]=1;v[hx+1][hy-2]=1;v[hx-2][hy-1]=1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++) 
            if(v[i][j]==1) f[i][j]=0; //跳过马的控制区
            else f[i][j]=f[i-1][j]+f[i][j-1];  //递推
    printf("%lld",f[n][m]); //(n,m)即为答案
    return 0;
} 
 
原文地址:https://www.cnblogs.com/yanyiming10243247/p/9237132.html