P1002过河卒

P1002过河卒

给出的地图从(0,0)开始,先将地图向右下方偏移,使原点变为(1,1)

cin >> n >> m >> x >> y;
m++, n++, x++, y++;//将地图向右下方偏移,让地图原点变为(1,1)

读入马的坐标后标记出所有马能走的坐标,剩下的点就是卒能走到的点

int dx[8] = {1, 1, -1, -1, 2, 2, -2, -2};
int dy[8] = {2, -2, 2, -2, 1, -1, 1, -1};
for (int i = 0; i < 8; i++)
{
	int xx = x + dx[i], yy = y + dy[i];
	if(xx >= 1 && xx <= n && yy >= 1 && yy <= m)
	{
		mp[xx][yy] = true;//标记马的控制点
	}
}

设状态dp(i, j)为从原点到(i, j)的路径数量

卒可以向下或者向右走,即对于点(i, j),只能从其上方和左侧到达
也就是(i - 1, j) 和(i, j - 1)这两个点

所以到达点(i, j)的路径数量=上方点的路径数量+左侧点的路径数量

可得状态转移方程

dp[i][j] = dp[i - 1][j] + dp[i][j - 1];

完整die码:

ll dp[N][N];
//dp[i][j]为(1,1)到当前点的路径数量

bool mp[N][N];
int dx[8] = {1, 1, -1, -1, 2, 2, -2, -2};
int dy[8] = {2, -2, 2, -2, 1, -1, 1, -1};

void solve() {
	int n, m, x, y;
	cin >> n >> m >> x >> y;
	m++, n++, x++, y++;//将地图向右下方偏移,让地图原点变为(0,0)

	dp[1][1] = 1;
	mp[x][y] = true;

	for (int i = 0; i < 8; i++)
	{
		int xx = x + dx[i], yy = y + dy[i];
		if(xx >= 1 && xx <= n && yy >= 1 && yy <= m)
		{
			mp[xx][yy] = true;//标记马能走到的坐标
		}
	}

	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++)
		{
			if(i == 1 && j == 1)
			{
				continue;
			}
			dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
			if(mp[i][j])
			{
				dp[i][j] = 0;//马的控制点无法到达,路径数量为0
			}
		}
	}

	cout << dp[n][m] << '\n';

	return;
}

posted @ 2023-10-05 15:52  ShadowDream  阅读(44)  评论(1)    收藏  举报