NOIP 2000 提高组 洛谷1004题(方格取数)解题思路与C++代码解析 动态规划优化路径选择

引言
洛谷1004题“方格取数”是算法竞赛中经典的动态规划问题,要求从网格中选取两条不交叉的路径,使路径上的数字和最大化。本文将结合您提供的代码,详细解析解题思路、动态规划状态设计、代码实现细节,并融入SEO优化技巧,帮助读者深入理解算法逻辑,同时提升文章搜索引擎友好度。
一、题目描述
简要描述题目:例如,在一个n×n的方格图中,每个格子包含一个正整数。需要选择两条从左上角到右下角的路径,路径可重复经过格子,但两条路径除起点和终点外不能相交。求两条路径数字和的最大值。
二、解题思路与算法分析
1. 问题分析
2. 动态规划设计
(1)状态定义使用四维数组f[k][i][j]
表示:
k
:两条路径共同走过的步数(即第k步);i
:第一条路径当前所在的行坐标; j
:第二条路径当前所在的列坐标。状态值f[k][i][j]
为两条路径分别走到(i,j)和某个位置时的最大数字和。
(2)边界条件
f[0][1][1] = g[1][1]
(两条路径均从起点(1,1)出发,数字和为起点格子值)。 其他状态初始化为负无穷(-0x3f
),避免非法状态影响结果。
(3)状态转移方程分情况讨论:
i == j
时,两条路径在同一位置(重复点),只能同时向下或向右移动: (注:g[i][k+2-i]
表示当前重复点的数字,因为两条路径同时移动一步。)i!= j
时,两条路径独立移动,可分别向下或向右: (注:g[i][k+2-i]
和g[j][k+2-j]
分别表示两条路径当前位置的数字。)(4)最终答案:f[2*n-2][n][n]
(两条路径均到达右下角时的最大和)。
边界处理:通过min(n, k+1)
限制循环范围,避免无效计算。
#include <iostream> #include <algorithm> #include <cstring> using namespACe std; const int N = 15; // 网格最大维度 int g[N][N], f[N*2][N][N]; // g存储原网格,f为动态规划数组 int main() { int n, x, y, v; // n为网格大小,x,y,v为输入的坐标和值 cin >> n; // 读取网格大小 // 输入网格数据(注意:用户代码可能未处理EOF情况,但洛谷题目通常无影响) while((cin >> x >> y >> v) && (x || y || v)) { g[x][y] = v; // 将数据存入g数组 } // 初始化动态规划数组(除起点外,其余状态设为负无穷) memset(f, -0x3f, sizeof f); f[0][1][1] = g[1][1]; // 起点状态:两条路径均从(1,1)出发,和为g[1][1] // 动态规划主循环 for(int k = 1; k <= 2*n-2; ++k) { // k为总步数(两条路径共走2n-2步) for(int i = 1; i <= min(n, k+1); ++i) { // 第一条路径的行坐标 for(int j = 1; j <= min(n, k+1); ++j) { // 第二条路径的列坐标 int &val = f[k][i][j]; // 引用简化代码 val = max({ f[k-1][i][j], // 路径1不动,路径2移动 f[k-1][i-1][j], // 路径1向下,路径2不动 f[k-1][i][j-1], // 路径1不动,路径2向右 f[k-1][i-1][j-1] // 路径1向下,路径2向右 }); if(i == j) val += g[i][k+2-i]; // 重复点:两条路径同时移动,加一次数字 else val += g[i][k+2-i] + g[j][k+2-j]; // 非重复点:两条路径分别移动,加两次数字 } } } // 输出结果 cout << f[2*n-2][n][n] << endl; // 两条路径均到达右下角时的最大和 return 0; }
f[k][i][j]
的循环顺序:先遍历步数k,再遍历坐标i和j,确保状态依赖正确。min(n, k+1)
限制循环范围,避免超出网格边界。 使用max({})
语法简化状态转移表达式,提升代码可读性。
扩展方向:若网格规模更大,可尝试更激进的空间优化(如滚动数组+对称性压缩),或结合剪枝策略减少无效状态计算。
六、总结
洛谷1004题通过动态规划的四维状态设计,巧妙解决了两条不交叉路径的最优选择问题。用户提供的代码通过滚动数组优化空间,利用简洁的状态转移方程高效求解。掌握此类问题的关键在于理解状态定义与路径不交叉的约束条件,结合合理的边界处理,可实现高效算法。
原创内容 转载请注明出处