60. 礼物的最大价值 (未理解)

边界问题

问题1:状态表示
问题2:状态如何计算
问题3:边界

问题1:状态表示          f(i,j),表示从左上角走到(i,j)这个格子时,我拿到礼物的价值是多少
问题2:状态如何计算   f(i,j)=max{f[i-1,j],f[i,j-1]}+gift[i,j]
                                          其中:gift[i,j]为目标格子的礼物价值;
                max{f[i-1,j],f[i,j-1]}为到达目标前的累计礼物最大值
问题3:边界   f[i,0]=f[0,j]=0
答案:f(n,m)

class Solution {
public:
    int getMaxValue(vector<vector<int>>& grid) {

        int m = grid.size(), n = grid[0].size();
        vector<vector<int>> f(m + 1, vector<int>(n + 1));//下标从1开始算,从1开始算,不用处理边界问题。从1开始算,i-1其实是0
        // 从1开始可以不用处理边界问题
        for(int i = 1; i <= m; i ++){
            for(int j = 1; j <= n; j ++){
                //因为我们的i,j是从1开始算的,所以进行了i-1,j-1。所以i和j都要往前偏1个
                f[i][j] = max(f[i - 1][j] + grid[i - 1][j - 1], f[i][j - 1] + grid[i - 1][j - 1]);
        //cout <<"f[i - 1][j]="<<f[i - 1][j]<<" "<< "f[i][j - 1])=" <<f[i][j - 1]<<endl;
                //cout <<"grid[i - 1][j - 1]="<<grid[i - 1][j - 1]<<endl;
                //cout <<"f[i][j]="<<f[i][j]<<endl; } }
return f[m][n]; } };

代码中不理解,

1.为什么数组f的长度要定义成(m+1)*(n+1)

以测试函数为例,结合代码一步步看一下这是为什么?

 输入如上,则m=n=3,

f(m + 1, vector<int>(n + 1))为4*4;

为什么是4不是3呢?

看下图

 i=0~3, j=0~3除了(i=0,j=0)没有被用到,其他的都用了。所以数组f的长度要定义成(m+1)*(n+1)没毛病。

第二个问题,为什么f[i][j] = max(f[i - 1][j] + grid[i - 1][j - 1], f[i][j - 1] + grid[i - 1][j - 1]);用 的是 grid[i - 1][j - 1]而不是我们分析的grid[i][j]。

同样是结合输入数组

 for循环中i,j初始值为1,而g的下标是从0开始的,所以用 的是 grid[i - 1][j - 1]而不是我们分析的grid[i][j]

 

带女朋友搬家新家条件不好,累到女朋友了,让女朋友受苦了,特此明志:每天学习,明年这个时候(20190812)让女朋友住上大房子,永远年轻,永远热泪盈眶,很多人都是这样,他们都把自己当成身在梦中一样,浑浑噩噩地过日子,只有痛苦或爱或危险可以让他们重新感到这个世界的真实。
原文地址:https://www.cnblogs.com/make-big-money/p/12324482.html