当前位置:首页 > 入门组 > NOIP2002普及组过河卒题解:动态规划解法与代码详解

NOIP2002普及组过河卒题解:动态规划解法与代码详解

11小时前

NOIP2002普及组过河卒题解:动态规划解法与代码详解 NOIP普及组 动态规划算法 NOIP题解 洛谷题解 第1张

一、题目解读

“过河卒”是2002年NOIP普及组的经典题目(洛谷P1002),要求计算棋盘上卒从A点(0,0)到达B点(n,m)的路径条数。卒仅能向右或向下移动,但需避开马的控制点(马的位置及跳跃一步可达的点)。题目限制n、m≤20,需高效算法求解。

二、解题思路

采用动态规划(DP)。定义状态dp[i][j]为到达(i,j)点的合法路径数。核心思想是路径数由上方和左方转移而来,即dp[i][j] = dp[i-1][j] + dp[i][j-1]。需先标记马的控制点,避免路径经过禁区。

三、解题步骤

1. 输入与初始化:读入n、m及马的位置,创建dp和blocked数组标记控制点。

2. 标记控制点:通过方向数组dx,dy遍历马跳跃的8个方向,标记所有控制点。

3. 边界处理:初始化起点dp[0][0]=1,处理第一列/行路径(若不被控制,则路径数为上方/左方的累加)。

4. 动态规划循环:遍历(i,j),若(i,j)未被控制,则更新dp[i][j]为上方和左方路径之和。

5. 输出结果:dp[n][m]即终点路径数。

四、代码与注释

#include <iostream>  
#include <vector>  
using namespace std;  

// 马的控制点方向  
const int dx[] = {1, 1, -1, -1, 2, 2, -2, -2};  
const int dy[] = {2, -2, 2, -2, 1, -1, 1, -1};  

int main() {  
    int n, m, horse_x, horse_y;  
    cin >> n >> m >> horse_x >> horse_y;  
    
    // 创建棋盘并标记控制点  
    vector<vector<bool>> blocked(n+1, vector<bool>(m+1, false));  
    vector<vector<long long>> dp(n+1, vector<long long>(m+1, 0));  
    
    // 标记马的位置和控制点  
    blocked[horse_x][horse_y] = true;  
    for (int i = 0; i < 8; ++i) {  
        int nx = horse_x + dx[i];  
        int ny = horse_y + dy[i];  
        if (nx >= 0 && nx <= n && ny >= 0 && ny <= m) {  
            blocked[nx][ny] = true;  
        }  
    }  
    
    // 初始化起点  
    dp[0][0] = blocked[0][0]? 0 : 1;  
    
    // 处理第一列  
    for (int i = 1; i <= n; ++i) {  
        if (!blocked[i][0]) {  
            dp[i][0] = dp[i-1][0];  
        }  
    }  
    
    // 处理第一行  
    for (int j = 1; j <= m; ++j) {  
        if (!blocked[0][j]) {  
            dp[0][j] = dp[0][j-1];  
        }  
    }  
    
    // 动态规划计算路径数  
    for (int i = 1; i <= n; ++i) {  
        for (int j = 1; j <= m; ++j) {  
            if (!blocked[i][j]) {  
                dp[i][j] = dp[i-1][j] + dp[i][j-1];  
            }  
        }  
    }  
    
    cout << dp[n][m] << endl;  
    return 0;  
}

五、总结

本文通过动态规划解决“过河卒”问题,重点在于状态定义、边界初始化与马的控制点处理。代码利用vector简化边界判断,结合方向数组高效标记控制点,最终实现O(nm)时间复杂度。该解法对算法竞赛中的DP问题具有参考价值。


原创内容 转载请注明出处

分享给朋友:

相关文章

洛谷1656题解:基于Tarjan算法求解割边问题(附代码与详细步骤)

洛谷1656题解:基于Tarjan算法求解割边问题(附代码与详细步骤)

一、题目解读洛谷1656题要求在无向图中找出所有割边(即删除后导致图不连通的边)。题目核心在于判断图的连通性,并识别哪些边是“桥”。需理解图论中的连通分量概念,以及如何通过算法高效定位割边。二、解题思...

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

一、题目解读洛谷P2190题要求解决铁路售票系统中的车厢数量计算问题。题目给定n个车站和m条订票申请,每条申请包含区间[x,y)及乘客数z。需要计算在不超载的情况下(每节车厢最多36人),满足所有乘客...

【1999NOIP普及组】(洛谷P1016)旅行家的预算解题报告(附代码+注释)

【1999NOIP普及组】(洛谷P1016)旅行家的预算解题报告(附代码+注释)

一、题目解读题目要求解决旅行家从起点到终点(D1公里)的预算问题,需在沿途N个加油站中规划加油策略,使总费用最小化。每个加油站有不同油价和距离,汽车每升油可行驶D2公里,初始油量为C升,终点无加油站。...

洛谷2652题解析:同花顺排序问题的动态规划与滑动窗口优化

洛谷2652题解析:同花顺排序问题的动态规划与滑动窗口优化

一、题目解读洛谷2652题要求对一组扑克牌进行排序,目标是找到最少需要调整的次数,使得所有牌形成同花顺。题目中,扑克牌由花色和数字组成,需先按花色排序,再在同花色内按数字排序。核心难点在于如何处理花色...

洛谷P3694题解:动态规划与状态压缩优化解题全解析

洛谷P3694题解:动态规划与状态压缩优化解题全解析

一、题目解读洛谷P3694题要求解决一个多团队人数分配问题,给定n个元素和m个团队,每个元素属于一个团队,需将元素重新排列,使相邻元素属于不同团队,并最小化调整次数。题目难点在于如何高效处理团队间的空...

洛谷P1141题解:迷宫连通块问题的深度优先搜索算法与代码解析

洛谷P1141题解:迷宫连通块问题的深度优先搜索算法与代码解析

一、题目解读洛谷P1141题目要求处理一个由字符构成的迷宫,其中相同字符形成连通块,不同字符构成分隔。题目需统计连通块数量及大小,并支持查询两点是否属于同一连通块。核心在于高效识别并标记迷宫中的连通区...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。