洛谷P1002 过河卒

关于蒟蒻的我,刚刚接触DP....

 

那么就来做一道简单DP吧....

首先先看题:

题目描述

棋盘上AA点有一个过河卒,需要走到目标BB点。卒行走的规则:可以向下、或者向右。同时在棋盘上CC点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。

棋盘用坐标表示,AA点(0, 0)(0,0)、BB点(n, m)(n,m)(nn, mm为不超过2020的整数),同样马的位置坐标是需要给出的。

现在要求你计算出卒从AA点能够到达BB点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。

输入输出格式

输入格式:

 一行四个数据,分别表示BB点坐标和马的坐标。

 


输出格式:

 一个数据,表示所有的路径条数。

 

输入输出样例

输入样例#1:
6 6 3 3
输出样例#1:
6

说明

结果可能很大!

 

虽然简单,但AC过程还是那样艰巨...(好吧这道题因为简单有的人还在考虑它到达算不算DP...

 

废话少说,呈上AC代码,简单易懂...

此题一定要注意数据可能很大,要用long long类型!!!

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll; const int maxn = ; ll ans[maxn][maxn]; //用来存储答案(路径个数)
int vis[maxn][maxn]; //用来将卒不能走的点打标记
int dir1[] = {,,,,-,-,-,-}; //将马的横坐标变化方式存入dir1数组中
int dir2[] = {,-,,-,,-,,-}; //将马的纵坐标变化方式存入dir2数组中 int main()
{
int n,m,cx,cy; //用cx、cy分别存储马坐标的横纵坐标
cin>>n>>m>>cx>>cy;
memset(vis, , sizeof(vis)); //将打标记的vis数组进行初始化
vis[cx][cy] = ;//首先将马的坐标打标记,卒不能通过
for(int i = ; i < ; ++i){
int a = cx + dir1[i]; //用a来存储马能够达到的横坐标
int b = cy + dir2[i]; //用b来存储马能够达到的纵坐标
if(a >= && b >= && a <= n && b <= n){
vis[a][b] = ; //首先判断a、b两坐标所表示的点是否合法(即是否在棋盘中),然后将这个点标记为1,即卒不能到达
}
}
ans[][] = ; //从起点到起点的方案数为0(废话 构造递推式
for(int i = ; i <= n; ++i){
for(int j = ; j <= m; ++j){
if(i){ //若i为零,则不考虑上边的情况
if(vis[i][j]) ans[i][j] = ; //如果vis被标为1(即卒不能通过),则方案数为0
else ans[i][j] += ans[i-][j]; //如果vis仍为0 (即卒能通过),则进行递推
}
if(j){ //若j为零,则不考虑左边的情况
if(vis[i][j]) ans[i][j] = ; //如果vis被标为1(即卒不能通过),则方案数为0
else ans[i][j] += ans[i][j-]; //如果vis仍为0 (即卒能通过),则进行递推
}
}
}
cout<<ans[n][m]<<endl; //输出到(n,m)点方案数
return ;
}
上一篇:python正则表达式模块re:正则表达式常用字符、常用可选标志位、group与groups、match、search、sub、split,findall、compile、特殊字符转义


下一篇:python正则表达式中的分组 group