当前位置:首页 > 比赛题解 > 动态规划经典问题:NOIP传纸条问题详解与四维DP实现

动态规划经典问题:NOIP传纸条问题详解与四维DP实现

2周前 (06-20)比赛题解75

截图未命名.jpg 动态规划经典问题:NOIP传纸条问题详解与四维DP实现 动态规划 四维DP NOIP提高组 路径优化 算法竞赛 第1张

一、问题理解与算法选择

传纸条问题要求在一个m×n的矩阵中,从左上角到右下角传递两次纸条(路径不能重复),使得路径上数字之和最大。这个问题可以转化为寻找两条不相交的路径,使它们的和最大。动态规划是解决此类路径优化问题的理想选择,特别是使用四维dp来同时跟踪两条路径的状态。

二、完整代码实现(带详细注释)

#include <iostream>
#include <algorithm>
using namespACe std;

const int MAXN = 55;
int grid[MAXN][MAXN];  // 存储每个位置的好心程度
int dp[MAXN][MAXN][MAXN][MAXN];  // 四维DP数组

int main() {
    int m, n;
    cin >> m >> n;
    
    // 输入矩阵数据
    for(int i = 1; i <= m; i++) {
        for(int j = 1; j <= n; j++) {
            cin >> grid[i][j];
        }
    }
    
    // 动态规划处理
    for(int i1 = 1; i1 <= m; i1++) {
        for(int j1 = 1; j1 <= n; j1++) {
            for(int i2 = 1; i2 <= m; i2++) {
                for(int j2 = 1; j2 <= n; j2++) {
                    // 当前最大值来自四种可能的前驱状态
                    int curr = max(
                        max(dp[i1-1][j1][i2-1][j2], dp[i1-1][j1][i2][j2-1]),
                        max(dp[i1][j1-1][i2-1][j2], dp[i1][j1-1][i2][j2-1])
                    );
                    
                    // 如果两条路径走到同一个点,只加一次值
                    if(i1 == i2 && j1 == j2) {
                        dp[i1][j1][i2][j2] = curr + grid[i1][j1];
                    } else {
                        dp[i1][j1][i2][j2] = curr + grid[i1][j1] + grid[i2][j2];
                    }
                }
            }
        }
    }
    
    // 输出结果
    cout << dp[m][n][m][n] << endl;
    
    return 0;
}

三、算法核心解析

  1. 状态定义

    • dp[i1][j1][i2][j2]表示第一条路径到(i1,j1),第二条路径到(i2,j2)时的最大和

  2. 状态转移

    • 四种可能的前驱状态组合(上上、上左、左上、左左)

    • 使用max函数选择最优前驱

  3. 特殊处理

    • 当两条路径交汇时,只累加一次当前格的值

  4. 时间复杂度

    • O(m²n²),适用于m,n≤50的情况

四、优化思路

  1. 空间优化

    • 可降为三维DP,利用i1+j1 = i2+j2的性质

  2. 剪枝优化

    • 提前终止不可能产生最优解的状态

  3. 记忆化搜索

    • 可采用递归+记忆化的实现方式

五、常见问题解答

Q:为什么需要四维DP? A:因为要同时跟踪两条路径的位置,每个路径需要两个坐标。

Q:如何处理路径相交? A:当i1=i2且j1=j2时,只累加一次当前格的值。

Q:能否用DFS解决? A:理论上可以,但时间复杂度太高,不适合较大矩阵。


四维动态规划

原创内容 转载请注明出处

分享给朋友:

发表评论

访客

看不清,换一张

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