(地图型dp 算路径和最值)走迷宫2

题意:二维矩阵由左上角到右下角只能向右或向下走,求所有可能路径取值之和最大值

输入样例:

5 5

0   5   37   53   9
55 10 19    23   8
65 58 82   89   9
8   0   14   50   68
89 5   10   41    0

输出样例:

467

#include <iostream>
using namespace std;

int n,m;
int dp[1000][1000],g[1000][1000];
int main() {
    cin>>n>>m;
    for(int i=1;i<=n;i++){    //输入 矩阵 
        for(int j=1;j<=m;j++){
            cin>>g[i][j];
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            dp[i][j]=max(dp[i-1][j],dp[i][j-1])+g[i][j];//此时的最大值只能是左边一步或者上面一步走到,故此时取两者中最大值加上此时格子的值作为此时的dp值 
        }
    }
    cout<<dp[n][m];
    return 0;
}

 更进一步的:

某人从图的左上角出发,可以向下行走,也可以向右走,直到到达右下角 点。在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字 0)。
此人从 左上角 点到 右下角 点共走两次,试找出 2 条这样的路径,使得取得的数之和为最大。

输入样例:
8
2 3 13
2 6  6
3 5  7
4 4 14
5 2 21
5 6  4
6 3 15
7 2 14
0 0  0
输出样例:
67
思路:一个人走两次可以思考为两个人同时走一次,但是两个人走过的位置不能重了,可以用四维dp做

#include <iostream>
using namespace std;

int n,m;
int dp[100][100][100][100],g[1000][1000];
int main() {
    cin>>n;
    int x,y,v; 
    while(1){
        cin>>x>>y>>v;
        g[x][y]=v;
        if(x==y&&x==v&&x==0){
            break;
        }
    }
    for(int i=1;i<=n;i++)                  //四维dp算法  i,j表示第一个人走的路径   k,l表示第二个人走的路径 
        for(int j=1;j<=n;j++)
            for(int k=1;k<=n;k++)
                for(int l=1;l<=n;l++){                         //取第一个人上一次走完的最值 和第二个人上次走完的最值 二者再求一个最大值,加上第一个人位置和第二个人位置的值 
                    dp[i][j][k][l]=max(max(dp[i-1][j][k-1][l],dp[i][j-1][k-1][l]),max(dp[i-1][j][k][l-1],dp[i][j-1][k][l-1]))+g[i][j]+g[k][l];
                    if(i==k&&j==l){                            //第一个人和第二个人不能位置重了 重了则减去多加的部分 
                        dp[i][j][k][l]-=g[i][j];
                    }
                }
    cout<<dp[n][n][n][n];
    return 0;
}
原文地址:https://www.cnblogs.com/xusi/p/12719014.html