众所周知,牛妹有很多很多粉丝,粉丝送了很多很多礼物给牛妹,牛妹的礼物摆满了地板。
地板是
的格子,每个格子有且只有一个礼物,牛妹已知每个礼物的体积。
地板的坐标是左上角(1,1) 右下角(N, M)。
牛妹只想要从屋子左上角走到右下角,每次走一步,每步只能向下走一步或者向右走一步或者向右下走一步
每次走过一个格子,拿起(并且必须拿上)这个格子上的礼物。
牛妹想知道,她能走到最后拿起的所有礼物体积最小和是多少?
[[1,2,3],[2,3,4]]
7
先走到(1,1)这个点,此时和为1,然后走到(1,2)这个点,拿起(1,2)点的数字,此时和为3,最后走到(2,3),拿起(2,3)点的数字,此时和为7
0<N,M<3000<=每个礼物的体积<100
class Solution {
public:
/**
*
* @param presentVolumn int整型vector<vector<>> N*M的矩阵,每个元素是这个地板砖上的礼物体积
* @return int整型
*/
int selectPresent(vector<vector<int> >& presentVolumn) {
int n=presentVolumn.size(), m=presentVolumn[0].size();
if(n==0 || m==0)
return 0;
for(int i=1;i<m;i++)
presentVolumn[0][i] += presentVolumn[0][i-1];
for(int i=1;i<n;i++)
presentVolumn[i][0] += presentVolumn[i-1][0];
for(int i=1;i<n;i++)
for(int j=1;j<m;j++)
presentVolumn[i][j] += min(presentVolumn[i-1][j-1], min(presentVolumn[i-1][j], presentVolumn[i][j-1]));
return presentVolumn[n-1][m-1];
}
}; class Solution {
public:
/**
*
* @param presentVolumn int整型vector<vector<>> N*M的矩阵,每个元素是这个地板砖上的礼物体积
* @return int整型
*/
int selectPresent(vector<vector<int> >& presentVolumn) {
// write code here
if(presentVolumn.size()==0||presentVolumn[0].size()==0) return 0;
int i,j,sum;
int n=presentVolumn.size(),m=presentVolumn[0].size();
int dp[n][m];
dp[0][0]=presentVolumn[0][0];
for(i=1;i<n;i++){
dp[i][0]=dp[i-1][0]+presentVolumn[i][0];
}
for(j=1;j<m;j++){
dp[0][j]=dp[0][j-1]+presentVolumn[0][j];
}
int tmp;
for(i=1;i<n;i++){
for(j=1;j<m;j++){
tmp=min(dp[i-1][j-1],dp[i-1][j]);
tmp=min(dp[i][j-1],tmp);
dp[i][j]=tmp+presentVolumn[i][j];
}
}
return dp[n-1][m-1];
}
}; int selectPresent(vector<vector<int> >& pv) {
int n = pv.size(); if(n == 0) return 0;
int m = pv[0].size();
for(int i = 1; i < n; i++) pv[i][0] += pv[i-1][0];
for(int i = 1; i < m; i++) pv[0][i] += pv[0][i-1];
for(int i = 1; i < n; i++)
for(int j = 1; j < m; j++)
pv[i][j] += min(pv[i][j-1], min(pv[i-1][j], pv[i-1][j-1]));
return pv[n-1][m-1];
} import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param presentVolumn int整型二维数组 N*M的矩阵,每个元素是这个地板砖上的礼物体积
* @return int整型
*/
public int selectPresent (int[][] presentVolumn) {
// write code here
if (presentVolumn.length == 0 || presentVolumn[0].length == 0) {
return 0;
}
int[][] dp = new int[presentVolumn.length][presentVolumn[0].length];
for (int i = 0; i < dp.length; i++) {
for (int j = 0; j < dp[0].length; j++) {
dp[i][j] = Integer.MAX_VALUE;
}
}
for (int i = 0; i < presentVolumn.length; i++) {
for(int j = 0; j < presentVolumn[0].length; j++) {
if (i != 0 && j != 0) {
dp[i][j] = Math.min(dp[i][j], dp[i - 1][j - 1]);
}
if (i != 0) {
dp[i][j] = Math.min(dp[i][j], dp[i - 1][j]);
}
if (j != 0) {
dp[i][j] = Math.min(dp[i][j], dp[i][j - 1]);
}
if (dp[i][j] == Integer.MAX_VALUE) {
dp[i][j] = 0;
}
dp[i][j] += presentVolumn[i][j];
}
}
return dp[presentVolumn.length - 1][presentVolumn[0].length - 1];
}
} import java.util.*;
public class Solution {
/**
*
* @param presentVolumn int整型二维数组 N*M的矩阵,每个元素是这个地板砖上的礼物体积
* @return int整型
*/
public int selectPresent (int[][] presentVolumn) {
// write code here
int N=presentVolumn.length;
int M=presentVolumn[0].length;
return Cost(N-1,M-1,presentVolumn);
}
public int Cost(int N,int M,int[][] presentVolumn){
int key,a,b,c;
if(N>0&&M>0){
a=Cost(N-1,M,presentVolumn);
b=Cost(N,M-1,presentVolumn);
c=Cost(N-1,M-1,presentVolumn);
key=Math.min(Math.min(a,b),c)+presentVolumn[N][M];
}
else if(N==0&&M>0){
key=Cost(N,M-1,presentVolumn)+presentVolumn[N][M];
}
else if(N>0&&M==0){
key=Cost(N-1,M,presentVolumn)+presentVolumn[N][M];
}else{
key=presentVolumn[N][M];
}
return key;
}
} class Solution: def selectPresent(self , presentVolumn ): # write code here rows = len(presentVolumn) cols = len(presentVolumn[0]) if rows == 0&nbs***bsp;cols == 0: return 0 dp = [[0]*cols for i in range(rows)] dp[0] = presentVolumn[0].copy() for i in range(1, rows): dp[i][0] = presentVolumn[i][0] for i in range(1, cols): dp[0][i] += dp[0][i-1] for i in range(1, rows): dp[i][0] += dp[i-1][0] for i in range(1, rows): for j in range(1, cols): dp[i][j] = min(( dp[i-1][j-1], dp[i-1][j], dp[i][j-1] )) + presentVolumn[i][j] return dp[i][j]入门级DP题
class Solution: def selectPresent(self , presentVolumn ): # write code here if not presentVolumn: return 0 m = len(presentVolumn) n = len(presentVolumn[0]) dp = presentVolumn for i in range(1,m): dp[i][0]+=dp[i-1][0] for j in range(1,n): dp[0][j]+=dp[0][j-1] for i in range(1,m): for j in range(1,n): dp[i][j]+=min(dp[i-1][j-1],dp[i-1][j],dp[i][j-1]) return dp[m-1][n-1]动态规划的题,不过python通过的空间好高啊。。。
//动态规划,左边,左上,上边元素最优的最优(最小值)加上元素本身是为最优。
public int selectPresent (int[][] presentVolumn) {
int n = presentVolumn.length;
int m = presentVolumn[0].length;
int[][] dp = new int[n+1][m+1];
for(int i = 0;i<=n ;i++){
dp[i][0] = Integer.MAX_VALUE;
}
for(int i = 0;i<=m ;i++){
dp[0][i] = Integer.MAX_VALUE;
}
dp[1][1] = presentVolumn[0][0];
for(int i=0;i<n;i++){
int j=0;
if(i==0){
j=1;
}
for(;j<m;j++){
dp[i+1][j+1] = Math.min(dp[i][j],Math.min(dp[i+1][j],dp[i][j+1])) + presentVolumn[i][j];
}
}
return dp[n][m];
} import java.util.Stack;
public class Solution {
/**
*
* @param presentVolumn int整型二维数组 N*M的矩阵,每个元素是这个地板砖上的礼物体积
* @return int整型
*/
public int selectPresent (int[][] presentVolumn) {
int row = 0, col = 0;
int[][] dp = new int[presentVolumn.length][presentVolumn[0].length];
dp[row][col] = presentVolumn[row][col];
Stack<Integer> rowStack = new Stack<Integer>();
rowStack.push(row);
Stack<Integer> colStack = new Stack<Integer>();
colStack.push(col);
while (!rowStack.isEmpty()) {
row = rowStack.pop();
col = colStack.pop();
if (row + 1 < presentVolumn.length) {
if (dp[row + 1][col] == 0) {
dp[row + 1][col] = dp[row][col] + presentVolumn[row + 1][col];
rowStack.push(row + 1);
colStack.push(col);
} else {
dp[row + 1][col] = Math.min(dp[row + 1][col], dp[row][col] + presentVolumn[row + 1][col]);
}
}
if (col + 1 < presentVolumn[0].length) {
if (dp[row][col + 1] == 0) {
dp[row][col + 1] = dp[row][col] + presentVolumn[row][col + 1];
rowStack.push(row);
colStack.push(col + 1);
} else {
dp[row][col + 1] = Math.min(dp[row][col + 1], dp[row][col] + presentVolumn[row][col + 1]);
}
}
if (row + 1 < presentVolumn.length && col + 1 < presentVolumn[0].length) {
if (dp[row + 1][col + 1] == 0) {
dp[row + 1][col + 1] = dp[row][col] + presentVolumn[row + 1][col + 1];
rowStack.push(row + 1);
colStack.push(col + 1);
} else {
dp[row + 1][col + 1] = Math.min(dp[row + 1][col + 1], dp[row][col] + presentVolumn[row + 1][col + 1]);
}
}
}
return dp[presentVolumn.length - 1][presentVolumn[0].length-1];
}
} import java.util.*;
public class Solution {
/**
*
* @param presentVolumn int整型二维数组 N*M的矩阵,每个元素是这个地板砖上的礼物体积
* @return int整型
*/
public int selectPresent (int[][] presentVolumn) {
if(presentVolumn == null || presentVolumn.length == 0){
return 0;
}
int n = presentVolumn.length;
int m = presentVolumn[0].length;
int[][] dp = new int[n+1][m+1];
for(int i=1;i<=n;i++){
dp[i][1] = presentVolumn[i-1][0] + dp[i-1][1];
}
for(int i=1;i<=m;i++){
dp[1][i] = presentVolumn[0][i-1] + dp[1][i-1];
}
for(int i=2;i<=n;i++){
for(int j=2;j<=m;j++){
dp[i][j] = presentVolumn[i-1][j-1] + Math.min(Math.min(dp[i-1][j], dp[i][j-1]), dp[i-1][j-1]);
}
}
return dp[n][m];
}
}
public class Solution {
/**
*
* @param presentVolumn int整型二维数组 N*M的矩阵,每个元素是这个地板砖上的礼物体积
* @return int整型
*/
public int selectPresent (int[][] presentVolumn) {
// 数组大小为0时返回0
if (presentVolumn.length == 0 || presentVolumn[0].length == 0){
return 0;
}
int n = presentVolumn.length;
int m = presentVolumn[0].length;
// 初始化数组
int dp[][] = presentVolumn;
// 初始化第一行
for (int i = 1; i < n; i++){
dp[i][0] += dp[i - 1][0];
}
// 初始化第一列
for (int j = 1; j < m; j++){
dp[0][j] += dp[0][j - 1];
}
// 当前位置最小值为(左上,上,左中最小值加上当前值)
for (int i = 1; i < n; i++){
for (int j = 1; j < m; j++){
dp[i][j] += Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]);
}
}
return dp[n- 1][m - 1];
}
} class Solution:
def selectPresent(self , presentVolumn ):
# write code here
# 首先考虑数组为空的情况
if not presentVolumn: return 0
# 计算出数组的维度
N, M = len(presentVolumn),len(presentVolumn[0])
# 初始化dp数组
dp = [[float("inf") for i in range(M+1)] for j in range(N+1)]
dp[0][0] = 0
for i in range(1,N+1):
dp[i][0] = dp[i-1][0] + presentVolumn[i-1][0]
for j in range(1,M+1):
dp[0][j] = dp[0][j-1] + presentVolumn[0][j-1]
for i in range(1,N+1):
for j in range(1,M+1):
# 状态转移方程
dp[i][j] = presentVolumn[i-1][j-1] + min(dp[i-1][j],dp[i-1][j-1],dp[i][j-1])
return dp[N][M] import java.util.*;
public class Solution {
/**
*
* @param presentVolumn int整型二维数组 N*M的矩阵,每个元素是这个地板砖上的礼物体积
* @return int整型
*/
public int selectPresent (int[][] presentVolumn) {
// write code here
if (presentVolumn == null || presentVolumn.length == 0 || presentVolumn[0].length == 0)
return 0;
int N = presentVolumn.length;
int M = presentVolumn[0].length;
int[][] matrix = presentVolumn;
for (int i = 1; i < N; i++) {
matrix[i][0] += matrix[i - 1][0];
}
for (int j = 1; j < M; j++) {
matrix[0][j] += matrix[0][j - 1];
}
for (int i = 1; i < N; i++) {
for (int j = 1; j < M; j++) {
matrix[i][j] += Math.min(Math.min(matrix[i - 1][j], matrix[i][j - 1]), matrix[i - 1][j - 1]);
}
}
return matrix[N - 1][M - 1];
}
} class Solution: def selectPresent(self , presentVolumn ): if not presentVolumn: return 0 N = len(presentVolumn) M = len(presentVolumn[0]) pd = [[0 for col in range(M)] for row in range(N)] # 用来记录到达每一位置最少的体积和 pd[0][0] = presentVolumn[0][0] for i in range(1, N): # 记录第一列每个位置的最小体积和 pd[i][0] = pd[i - 1][0] + presentVolumn[i][0] for j in range(1, M): # 记录第一行每个位置的最小体积和 pd[0][j] = pd[0][j - 1] + presentVolumn[0][j] for i in range(1, N): # 记录其他所有位置的最小体积和 for j in range(1, M): pd[i][j] = min(pd[i - 1][j], pd[i][j - 1], pd[i - 1][j - 1]) + presentVolumn[i][j] return pd[N - 1][M - 1]