赞
踩
一个机器人在m×n大小的地图的左上角(起点)。机器人每次可以向下或向右移动。机器人要到达地图的右下角(终点)。可以有多少种不同的路径从起点走到终点?
class Solution { public: /** * * @param m int整型 * @param n int整型 * @return int整型 */ int uniquePaths(int m, int n) { // write code here vector<vector<int>> ret(m, vector<int>(n, 1));//m-row,n-col //初始条件 第一行 = 第一列 = 1 for(int i = 0; i < m; ++i) ret[i][0] = 1; for(int i = 0; i < n; ++i) ret[0][i] = 1; //状态转移方程 for(int i = 1; i < m; i++) { for(int j = 1; j < n; j++) { ret[i][j] = ret[i][j-1] + ret[i-1][j]; } } return ret[m-1][n-1]; } };
给定一个由非负整数填充的m x n的二维数组,现在要从二维数组的左上角走到右下角,请找出路径上的所有数字之和最小的路径。注意:你每次只能向下或向右移动。
min(F(i-1, j) + F(i, j-1)) + array[i][j]
F(0, 0) = array[0][0]
F(i, 0) = F(i-1, 0) + array[i][0]
F(0, j) = F(0, j-1) + array[0][j]
class Solution { public: /** * * @param grid int整型vector<vector<>> * @return int整型 */ int minPathSum(vector<vector<int> >& grid) { // write code here vector<vector<int>> ret(grid); int row = grid.size(); int col = grid[0].size(); //初始条件 for(int i = 1; i < row; i++) ret[i][0] = ret[i-1][0] + grid[i][0]; for(int i = 1; i < col; i++) ret[0][i] = ret[0][i-1] + grid[0][i]; //转移方程 for(int i = 1; i < row; ++i) { for(int j = 1; j < col; ++j) { ret[i][j] = min(ret[i-1][j], ret[i][j-1]) + grid[i][j]; } }【 return ret[row-1][col-1]; } };
有 n 个物品和一个大小为 m 的背包. 给定数组 A 表示每个物品的大小和数组 V 表示每个物品的价值。问最多能装入背包的总价值是多大?
状态范围索引是从1开始,价值数组和大小数组索引范围是从0开始,故第i个商品的容量为A[i-1],价值为V[i-1]
这里就要用到二维数组来表示价值和容量的关系。
情况1:放入第i个商品但是要取出某个商品 F(i, j) = F(i-1, j - A[i-1]) + V[i],j-A[i-1]表示容量要扣除掉第i个商品的体积【是第2种情况的子情况,因为对于背包的容量来说情况1和2都没超重】;
情况2:放入第i个商品 F(i, j) = F(i-1, j) + V[i]
情况3:不放入第i个商品,F(i, j) = F(i-1, j)【第i个商品放不下的时候,就会直接退化到上一个商品的状态值】
状态描述F(i, j) : 表示把第i个物品放入容量为j的背包中,此时该背包价值最大。
状态转移方程:如果A[i-1] > j ,表示情况3不放入第i个商品,F(i, j) = F(i-1, j);如果A[i-1] <= j,表示情况1和2放入第i个商品,F(i, j) = max(F(i-1, j), F(i-1, j - A[i-1]) + V[i-1]);
初始值:F(0, j) = 0 表示包有足够的容量,但是没有放入任何商品,价值为0;F(i, 0) = 0表示包容量为0,故价值为0
返回 : F(n, m)
class Solution { public: /** * @param m: An integer m denotes the size of a backpack * @param A: Given n items with size A[i] * @param V: Given n items with value V[i] * @return: The maximum value */ int backPackII(int m, vector<int> A, vector<int> V) { //若无商品或者无背包,则直接返回0 if(A.empty() || V.empty() || m < 1) return 0; //多加一行一列,给初始条件赋值 const int N = A.size() + 1;//物品个数 const int M = m + 1;//背包数 //初始条件 F(i, 0) = F(0, j) = 0 vector<vector<int>> ret(N, vector<int>(M, 0)); //状态递推 for(int i = 1; i < N; ++i) { for(int j = 1; j < M; ++j) { //第i个商品在A中对应的索引为i-1: i从1开始 //如果第i个商品大于j,说明放不下, 所以(i,j)的最大价值和(i-1,j)相同 if(A[i-1] > j) ret[i][j] = ret[i-1][j]; else ret[i][j] = max(ret[i-1][j], ret[i-1][j-A[i-1]] + V[i-1]); } } return ret[N-1][m]; } }; //用一维数组实现,内内层循环要从后往前更新 const int N = A.size();//物品个数 const int M = m + 1;//背包数 vector<int> ret(M, 0); for(int i = 1; i <= N; ++i) { for(int j = M - 1; j > 0; --j) { if(A[i] <= j) ret[j] = max(ret[j], ret[j-A[i]] + V[i]); else ret[j] = ret[j]; } } return ret[m];
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。