【问题描述】
动态规划实现:
- 卒只能向下或者向右,状态转移方程故为
dp[i][j]=max(dp[i-1][j]+dp[i][j-1],dp[i]j=[j])
,这个状态转移方程算的是当前坐标下,从原点到该坐标(只能向下或向右)的路径条数。最后输出对应的dp[n][m]
即为答案。 - 定义一个判断函数,判断目前的坐标是否是马可以到达的点,或者是马自身的坐标。
#include<iostream>
#include<algorithm>
using namespace std;
long long dp[30][30];
int m_x[8]={-2,-2,-1,-1,1,1,2,2},m_y[8]={1,-1,2,-2,2,-2,1,-1};
int main(){
int n,m,x,y;
cin>>n>>m>>x>>y;
n+=1;
m+=1;
x+=1;
y+=1;
for(int i=0;i<8;i++){
if(x+m_x[i]>=1&&x+m_x[i]<=n&&y+m_y[i]>=1&&y+m_y[i]<=m)
dp[x+m_x[i]][y+m_y[i]]=-1;
}
dp[1][0]=1;
dp[x][y]=-1;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(dp[i][j]==-1)
dp[i][j]=0;
else{
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
}
cout<<dp[n][m];
return 0;
}
递推实现:
#include<iostream>
#include<cstring>
using namespace std;
long long a[30][30];
int vis[30][30];
int next[][2]={{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}};
int main()
{
int n,m;
int x,y;
int nx,ny;
int i,j;
memset(vis,0,sizeof(vis));
cin>>n>>m>>x>>y;
a[0][0]=0;
vis[x][y]=1;
a[x][y]=0;
for(i=0;i<8;i++)
{
nx=x+next[i][0];
ny=y+next[i][1];
if(0<=nx&&nx<=n&&0<=ny&&ny<=m)
{
vis[nx][ny]=1;
a[nx][ny]=0;
}
}
for(i=0;i<=n;i++)
{
if(vis[i][0]==1)
while(i<=n)
{
i++;
a[i][0]=0;
}
else
a[i][0]=1;
}
for(j=0;j<=m;j++)
{
if(vis[0][j]==1)
while(j<=m)
{
j++;
a[0][j]=0;
}
else
a[0][j]=1;
}
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
if(vis[i][j]==0)
a[i][j]=a[i][j-1]+a[i-1][j];
cout<<a[n][m]<<endl;
return 0;
}