牛妹的礼物解题记录
题目描述
众所周知,牛妹有很多很多粉丝,粉丝送了很多很多礼物给牛妹,牛妹的礼物摆满了地板。
地板是N\times MN×M的格子,每个格子有且只有一个礼物,牛妹已知每个礼物的体积。
地板的坐标是左上角(1,1) 右下角(N, M)。
牛妹只想要从屋子左上角走到右下角,每次走一步,每步只能向下走一步或者向右走一步或者向右下走一步
每次走过一个格子,拿起(并且必须拿上)这个格子上的礼物。
牛妹想知道,她能走到最后拿起的所有礼物体积最小和是多少?
示例1
输入
复制
[[1,2,3],[2,3,4]]
输出
复制
7
说明
(1,1)->(1,2)->(2,3)
备注:
0<N,M<300
每个礼物的体积小于100
我的解法:
```java
import java.util.*;
public class Solution {
public int selectPresent (int[][] presentVolumn) {
if(presentVolumn.length == 0)
{
return 0;
}
if(presentVolumn.length == 1)
{
int res = 0;
for(int i = 0;i<presentVolumn[0].length;++i)
{
res += presentVolumn[0][i];
}
return res;
}
if(presentVolumn[0].length == 1)
{
int res = 0;
for(int i = 0;i<presentVolumn.length;++i)
{
res += presentVolumn[i][0];
}
return res;
}
int[][] resVolumn = presentVolumn;
for (int i = 1;i < presentVolumn[0].length;++i)
{
resVolumn[0][i] = resVolumn[0][i-1]+resVolumn[0][i];
}
for (int i = 1;i < presentVolumn.length;++i)
{
resVolumn[i][0] = resVolumn[i-1][0]+resVolumn[i][0];
}
int i = 0;
int j = 0;
for(i = 1;i<presentVolumn.length;++i)
{
for(j = 1;j<presentVolumn[i].length;++j)
{
int sum1 = resVolumn[i-1][j]+ resVolumn[i][j];
int sum2 = resVolumn[i][j-1]+ resVolumn[i][j];
int sum3 = resVolumn[i-1][j-1]+ resVolumn[i][j];
int minValue = sum1 < sum2? sum1:sum2;
minValue = minValue < sum3?minValue:sum3;
resVolumn[i][j] = minValue;
}
}
/*for(int k = 0;k<resVolumn.length;++k)
{
for(int l = 0;l<resVolumn[0].length;++l)
{
System.out.print(resVolumn[k][l]);
System.out.print(" ");
}
System.out.println();
}*/
return resVolumn[i-1][j-1];
}
}
思路:每个点的值取决于上方格子数,左方格子数,和左上方格子数,这三个值加上当前点值的最小值为该格子的最小值,根据输入的数组算出结果数组,结果数组的每个值就是从左上角到该点的和的最小值。右下角的格子就是从左上角到右下角的和的最小值。注意要初始化第一行和第一列。只有一行或一列时只需将每个元素相加即可。注意判空数组。
看了网友的解法,发现自己写的单独考虑一行或一列是没必要的,初始化第一行和第一列其实已经包含计算只有一行或一列的情况了。