📣 独立日限时特惠: VIP通行证立减$68
查看: 3749| 回复: 13
跳转到指定楼层
上一主题 下一主题
收起左侧

[动态规划] 问一道狗家onsite的DP题 不太懂

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
Leetcode上看到的最近newgrad的onsite题目,类似于knapsack,实在想不出来这个DP关系应该怎么写,有没有大神来看看解析一下

Given digits 1-9 with each digit associated with a value. Now we have a wall that needs to be painted with those digits and each digit painted requires the value volume, you need to form the largest number possible from this. Given that the sum of the volume of the number is equal to the wall volume.

Input:
1 2 3 4 5 6 7 8 9
1 3 1 5 6 7 2 5 2
wall volume: 5
Output: 33333

(原贴地址:https://leetcode.com/discuss/int ... rad-feb-2020-reject

评分

参与人数 1大米 +2 收起 理由
lemoncorn1123 + 2 很有用的信息!

查看全部评分


上一篇:给大家推荐一个刷leetcode看最优解的小tip
下一篇:Leetcode刷题记录贴
推荐
bydstand 2020-3-16 11:51:20 | 只看该作者
全局:
Actuant 发表于 2020-3-14 02:59
我是这么想的,dp代表用volume i的时候的答案,i可以取0, 1, ..., volume,最后返回dp的最后一位。

构建 ...

能不能直接算出最后答案是几位数?例如五位数必然比四位数大,所以选择volume最小的digit,volume相同时选择更大的数字。
回复

使用道具 举报

推荐
Actuant 2020-3-14 02:59:54 | 只看该作者
全局:
我是这么想的,dp[i]代表用volume i的时候的答案,i可以取0, 1, ..., volume,最后返回dp的最后一位。

构建一个hashmap, 存下来每个vol对应的最大value是多少。对于1 3 1 5 6 7 2 5 2来说,dict[1] = 3

转移方程是:dp[i] = max(dp[i-j] * 10 + dict[j]), for j = 1, 2, ..., min(i, 9),这里假设每位最多是9

下面是code, time和space complexity是O(n),可能有大神有更好的解法:


  1. import collections

  2. class Solution:
  3.         def find_largest_num(self, nums, volume):
  4.                
  5.                 vol_dict = {}
  6.                 for i, num in enumerate(nums):
  7.                         vol_dict[num] = i + 1

  8.                 dp = [0] * (volume + 1)

  9.                 for i in range(1, volume + 1):
  10.                         for j in range(1, min(i + 1, 10)):
  11.                                 if j not in vol_dict:
  12.                                         continue
  13.                                 dp[i] = max(dp[i], dp[i - j] * 10 + vol_dict[j])

  14.                 return dp[-1]


  15. if __name__ == '__main__':
  16.         s = Solution()
  17.         nums = [1, 3, 1, 5, 6, 7, 2, 5, 2]
  18.         print(s.find_largest_num(nums, 5))
复制代码
回复

使用道具 举报

推荐
lpl1998 2020-3-16 17:09:21 | 只看该作者
全局:
首先要尽可能多选digits,在确定了digits数量后,要使得高位尽可能大。

dp[i]表示volume为i时最多可以选多少个数。这个类似背包的思路跑一下就可以算出来。

在跑的时候,对于每一个dp[i],需要记录是选择了哪个digit转移过来的。

这里可能有多个状态可以转移到dp[i],选择一个可以让当前digit最大的状态转移就可以了。(因为高位digit要尽可能大)

这样从dp[volume]倒推回去,把每步转移的digit连起来,倒过来就是答案了。

随手yy的,欢迎指正orz
回复

使用道具 举报

🔗
chgwang 2020-3-16 02:53:53 | 只看该作者
全局:
Actuant 发表于 2020-3-13 13:59
我是这么想的,dp代表用volume i的时候的答案,i可以取0, 1, ..., volume,最后返回dp的最后一位。

构建 ...

这个解法很好,我觉得一个可能的follow up是,如果不是用的不是python,这个方程dp = max(dp[i-j] * 10 + dict[j])直接用 ,如果volume很大的话,可能会integer overflow.
回复

使用道具 举报

🔗
loveltyoic 2020-3-16 20:25:00 | 只看该作者
全局:
Actuant 发表于 2020-3-14 02:59
我是这么想的,dp代表用volume i的时候的答案,i可以取0, 1, ..., volume,最后返回dp的最后一位。

构建 ...

转移的时候也可以加到前面吧,感觉要求一个max(pow(10, dp[i-j]的位数-1) * vol_dict[j], dp[i - j] * 10 + vol_dict[j])
回复

使用道具 举报

🔗
david_smith 2020-3-16 22:03:25 | 只看该作者
全局:
没看懂这个题目。 谁可以认真解释下这个Input output呢?
Input:
1 2 3 4 5 6 7 8 9
1 3 1 5 6 7 2 5 2
wall volume: 5
Output: 33333
回复

使用道具 举报

🔗
 楼主| miawallace 2020-3-16 22:29:53 | 只看该作者
全局:
david_smith 发表于 2020-3-16 22:03
没看懂这个题目。 谁可以认真解释下这个Input output呢?
Input:
1 2 3 4 5 6 7 8 9

这个input第一行是数字,第二行是数字对应的volume
就是数字1的volume是1,数字2的volume是3,数字3的volume是1,etc
回复

使用道具 举报

🔗
黄蝉 2020-3-16 23:25:29 | 只看该作者
全局:
bydstand 发表于 2020-3-16 11:51
能不能直接算出最后答案是几位数?例如五位数必然比四位数大,所以选择volume最小的digit,volume相同时 ...

我也感觉没太看明白,既然每位数字对应的值只是从1-9,那么只需要找到1对应的最大值,需要的wall volume是几就是由这个最大值构建成的几位数是不是就可以了?毕竟位数大一定比位数小的大。不过我的理解可能有问题,不会这么直接吧。
回复

使用道具 举报

无效楼层,该帖已经被删除
您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表