剑指Offer - 面试题47:礼物的最大价值

简介: 剑指Offer - 面试题47:礼物的最大价值

题目

在一个m*n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向左向下移动一格,直到到达棋盘的右下角。给定一个棋盘及其上面的礼物,请计算你最多能拿到多少价值的礼物?

例如,在下面的棋盘中,如果沿着带下画线的数字的路线(1、12、5、7、7、16、5)。那么我们能拿到最大价值为53的礼物。

分析

动态规划


我们创建一个等同棋盘的二维数组,每个位置用记录前一步到这一步的能拿到的最多价值。

如下图,每一步都是拿到的最多价值。空间复杂度为O(n2);

C++

#include <iostream>
using namespace std;
int getMaxValue_sonlution(const int* values, int rows, int cols)
{
  if (values == nullptr || rows <= 0 || cols <= 0)
    return 0;
  int** temp = new int*[rows];//用来存储每步的做大价值
  for (int i = 0; i < rows; ++i)
  {
    temp[i] = new int[cols];
  }
  for (int i = 0; i < rows; ++i)
  {
    for (int j = 0; j < cols; ++j)
    {
      //保存前一步的最大价值 max(values[i-1][j]与values[i][j-1])
      int maxnum = 0; 
      if (0 == i && 0 == j) // 最开始
        ;
      else if (0 == i)    // 到最上边
        maxnum = temp[i][j - 1];
      else if (0 == j)    // 到最左边
        maxnum = temp[i - 1][j];
      else
        maxnum = max(temp[i][j - 1], temp[i - 1][j]);
      temp[i][j] = values[i * cols + j] +  maxnum;
    }
  }
  int set = temp[rows - 1][cols - 1];
  for (int i = 0; i < rows; ++i)
  {
    delete[] temp[i];
  }
  delete[] temp;
  return set;
}
int main()
{
  int n[4][4] =
  {
    {1,10,3,8},
    {12,2,9,6},
    {5,7,4,11},
    {3,7,16,5}
  };
  int ret = getMaxValue_sonlution(n[0], 4, 4);
  cout << "能拿到最大价值的礼物:" << ret << endl;
}


优化动态规划

因为我们每次向下和向右移动,所以我们可以用一维数组代替上面的二维数组,

空间复杂度为O(n);

C++

#include <iostream>
using namespace std;
int getMaxValue_sonlution(const int* values, int rows, int cols)
{
  if (values == nullptr || rows <= 0 || cols <= 0)
    return 0;
  int* temp = new int[cols];//用来存储每步的做大价值
  for (int i = 0; i < rows; ++i)
  {
    for (int j = 0; j < cols; ++j)
    {
      //保存前一步的最大价值 max(values[i-1][j]与values[i][j-1])
      int maxnum = 0; 
      if (0 == i && 0 == j) // 最开始
        ;
      else if (0 == i)    // 到最上边
        maxnum = temp[j - 1];
      else if (0 == j)    // 到最左边
        maxnum = temp[j];
      else
        maxnum = max(temp[j - 1], temp[j]);
      temp[j] = values[i * cols + j] +  maxnum;
    }
  }
  int ret = temp[cols - 1];
  delete[] temp;
  return ret;
}
int main()
{
  int n[4][4] =
  {
    {1,10,3,8},
    {12,2,9,6},
    {5,7,4,11},
    {3,7,16,5}
  };
  int ret = getMaxValue_sonlution(n[0], 4, 4);
  cout << "能拿到最大价值的礼物:" << ret << endl;
}


本章完!

目录
相关文章
|
15小时前
|
算法 测试技术 数据处理
【C/C++ 面试技巧】如何在简单的项目里突出自己的价值?
【C/C++ 面试技巧】如何在简单的项目里突出自己的价值?
55 1
|
7月前
|
Cloud Native 算法 Go
面试中的时间管理:如何在有限时间内展示最大价值
面试中的时间管理:如何在有限时间内展示最大价值
70 0
|
9月前
|
存储 安全 编译器
价值 1k 嵌入式面试题-单片机 main 函数之前都做了啥?
价值 1k 嵌入式面试题-单片机 main 函数之前都做了啥?
130 0
|
9月前
|
存储 网络协议 数据安全/隐私保护
价值 1k 嵌入式面试题-计算机网络 OSI
价值 1k 嵌入式面试题-计算机网络 OSI
|
11月前
|
机器学习/深度学习 人工智能 算法
强化学习从基础到进阶-常见问题和面试必知必答[2]:马尔科夫决策、贝尔曼方程、动态规划、策略价值迭代
强化学习从基础到进阶-常见问题和面试必知必答[2]:马尔科夫决策、贝尔曼方程、动态规划、策略价值迭代
|
11月前
|
机器学习/深度学习 人工智能 算法
强化学习从基础到进阶-常见问题和面试必知必答[1]:强化学习概述、序列决策、动作空间定义、策略价值函数、探索与利用、Gym强化学习实验
强化学习从基础到进阶-常见问题和面试必知必答[1]:强化学习概述、序列决策、动作空间定义、策略价值函数、探索与利用、Gym强化学习实验
|
JavaScript API 容器
一道价值25k的腾讯递归组件面试题(Vue3 + TS 实现)
小伙伴们好久不见,最近刚入职新公司,需求排的很满,平常是实在没时间写文章了,更新频率会变得比较慢。 周末在家闲着无聊,突然小弟过来紧急求助,说是面试腾讯的时候,对方给了个 Vue 的递归菜单要求实现,回来找我复盘。 正好这周是小周,没想着出去玩,就在家写写代码吧,我看了一下需求,确实是比较复杂,需要利用好递归组件,正好趁着这个机会总结一篇 Vue3 + TS 实现递归组件的文章。
|
前端开发 测试技术
深入解析价值25k的蚂蚁金服异步串行面试题
注:代码有错,请阅读原文。朋友去面试蚂蚁金服,遇到了一道面试题,乍一看感觉挺简单的,但是实现起来发现内部值得一提的点还是挺多的。
|
设计模式 SQL 缓存
和面试官的交谈:关于方向选择,未来的成长,价值的提升
和面试官的交谈:关于方向选择,未来的成长,价值的提升
|
15小时前
|
存储 Java
面试官:素有Java锁王称号的‘StampedLock’你知道吗?我:这什么鬼?
面试官:素有Java锁王称号的‘StampedLock’你知道吗?我:这什么鬼?
43 23