ACM 78. [NOIP2002] 过河卒(dp)

78. [NOIP2002] 过河卒

★   输入文件: pj024.in   输出文件: pj024.out    简单对比
时间限制:1 s   内存限制:128 MB

问题描述
如图,A点有一过河卒,需要走到目标B点。卒行走的规则:可以向下,或者向右。

同时在棋盘上的任一点有一个对方的马(如图中C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点。

例如上图C点的马可控制9个点(P1...P8C)。卒不能通过对方马的控制点。棋盘用坐标表示,A点(00),B点(nm)(nm为不超过20的整数,并有键盘输入),同样,马的位置坐标是需要给出的(约定:CA同时CB)。

现在要你计算出 卒从A点出发能够到达B点的路径的条数。

【输入格式】

输入

一行四个整数n,m,x,y

B点坐标(n,m)以及对马的坐标(x,y){不用判错}

【输出格式】

输出

一个整数(路径的条数)

【输入样例】

输入文件

6 6 3 2

输出文件

17


#include 
#include 

using namespace std;

#define MAX_N 21

int n,m,x,y;
int dp[MAX_N][MAX_N];
int dx[]={2,1,2,-1,-2,1,-1,-2};
int dy[]={1,2,-1,2,1,-2,-2,-1};
bool no[MAX_N][MAX_N];

int main()
{
    freopen("pj024.in","r",stdin);
    freopen("pj024.out","w",stdout);

    cin>>n>>m>>y>>x;

    for(int i=0;i<8;i++)
    {
        int nx=x+dx[i],ny=y+dy[i];
        if(nx>=0 && nx<=m && ny>=0 && ny<=n)
        {
            no[ny][nx]=true;
        }
    }
    no[y][x]=true;

    for(int i=0;i<=n;i++)
    {
        for(int j=0;j<=m;j++)
        {
            if(no[i][j]) continue;
            int cnt=0;

            if(i>=1 && !no[i-1][j]) cnt+=dp[i-1][j];
            if(j>=1 && !no[i][j-1]) cnt+=dp[i][j-1];
            dp[i][j]=cnt;
            if(i==0 && j==0) dp[0][0]=1;
        }
    }

    cout<


你可能感兴趣的:(DP)