(地图型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; }