在一个m*n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向左或者向下移动一格,知道到达棋盘的右下角。给定一个棋盘及其上面的礼物,请计算你最多能拿多少价值的礼物?
首先这里个人认为题目中对于移动的描述有错误,应该是每次向右或者向下移动。这是一道动态规划问题,对于(x,y)处,一定有两种方法到达,(x-1,y)或者(x,y-1)。如果要得到最大的礼物价值,上一步的时候肯定要选最大的。也就是max(f(left),f(up))。在具体的实现里面,这里构建了一个二维数组来存储各个位置所能得到的最大值。
1 int Dijkstra() 2 { 3 int x = v.size(), y = v[0].size(); 4 vector<bool>visit(x*y, false); 5 vector<int>value(x*y, 0); 6 value[0] = v[0][0]; 7 for (int i = 0; i < x*y; ++i) 8 { 9 int index = -1, maxV = -1; 10 for (int j = 0; j < value.size(); ++j) 11 { 12 if (visit[j] == false && maxV < value[j]) 13 { 14 maxV = value[j]; 15 index = j; 16 } 17 } 18 if (index == -1)break; 19 visit[index] = true; 20 for (int j = index + 1; j < x*y; ++j)//不能向回走 21 { 22 int ax = index / y, ay = index % y; 23 int bx = j / y, by = j % y; 24 if (visit[j] == false && abs((ax + ay) - (bx + by)) == 1) 25 { 26 if (value[j] < value[index] + v[bx][by]) 27 value[j] = value[index] + v[bx][by]; 28 } 29 } 30 } 31 return value.back(); 32 } 33 34 int DP() 35 { 36 vector<vector<int>>dp(v.size(), vector<int>(v[0].size(), 0)); 37 dp[0][0] = v[0][0]; 38 for (int i = 1; i < v[0].size(); ++i) 39 dp[0][i] = dp[0][i-1] + v[0][i]; 40 for (int i = 1; i < v.size(); ++i) 41 dp[i][0] = dp[i-1][0] + v[i][0]; 42 for (int i = 1; i < v.size(); ++i) 43 for (int j = 1; j < v[0].size(); ++j) 44 dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + v[i][j]; 45 return dp[v.size() - 1][v[0].size() - 1]; 46 }
原文:https://www.cnblogs.com/zzw1024/p/11695778.html