1002 过河卒
很简单的一道dp
题目很简单,我们就不分析了
首先我们得先说说思路:这道题我们得设置两个数组,一个a一个book,book数组是用来标记这个点卒能不能到,a数组记录方案数。
那么我们想想什么地方小卒过不了?马的四步
所以我们使用循环将马的四面八方用b标记一下,表示不能到达
然后我们就要推一推决策方程了
一个点的方案数由它左边的点的方案数加上它右边的方案数,也就是递推,递推是什么呢,一个数i的取值和前面i-1或者i-2的取值有关系,这就是递推,一个一个的传递下去即:
a[i][j]=a[i-1][j]+a[i][j-1]
但是不满足这个方程的地方呢?那就是边边,我们课题使用两个循环将边界值全部设置为1
这道题还挺简单的,简单的dp,最后只需要输出a[n][m]即可表示nm的方案数
还有一点需要强调,那就是数据范围,a数组的方案数会很大,所以不要忘记longlong,我一开始忘了,所以调了很长时间
-------------重新------------
所以,一定要判断取值的范围,也就是取值的类型,到底使用什么类型
通过后面重新的复习,我意识到一个问题
book[hang][0]==0
book[0][lie]==0
这两句话的精髓是什么
非常不好理解
为什么要进行一个判断?而且这个判断时只要遇见了马的位置就不能计算为1呢?
因为我们要计算的是方案,是路径,而不是步数
所以,马的位置(马的八个脚)会影响卒的走路方案
如果这一段没有马的影响(特殊指边界)那么一路无阻,自然就只有一种方案,最简单的方案值
那么只要有马的影响了,我们循环遇见了,那么后来的也不能按照1来计算了,因为马将路给堵住了,我们只能绕道,那么就只有好多的方案可以走了,所以后面的路不能按照1个方案计算
这样就明白了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
int n,m;
int x,y;//马的位置
bool book[300][300];
long long a[300][300];
int dx[8]={2,1,-1,-2,-2,-1,1,2};
int dy[8]={1,2,2,1,-1,-2,-2,-1};
int main()
{
cin>>n>>m>>x>>y;
book[x][y]=1;
for(int i=0;i<=7;i++)
{
if(x+dx[i]>=0&&x+dx[i]<=n&&y+dy[i]>=0&&y+dy[i]<=m)
{
book[x+dx[i]][y+dy[i]]=1;//将马的位置标记
}
}
int hang=0;
while(book[hang][0]==0&&hang<=n) a[hang++][0]=1;
int lie=0;
while(book[0][lie]==0&&lie<=m) a[0][lie++]=1;//两个循环搞边边不能过
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(book[i][j])
{
a[i][j]=0;
}
else
{
a[i][j]=a[i-1][j]+a[i][j-1];
}
}
}
cout<<a[n][m]<<endl;
return 0;
}
301

被折叠的 条评论
为什么被折叠?



