清晰解题: 网易笔试合唱团

闲言: 一切讲解不清晰的算法博文== 磨炼读者自学能力

本文参考合唱团——2016网易内推编程题

题目: 合唱团(网易编程题)

有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,要求相邻两个学生的位置编号的差不超过 d,使得这 k 个学生的能力值的乘积最大,你能返回最大的乘积吗?

输入描述:

  • 每个输入包含 1 个测试用例。每个测试数据的第一行包含一个整数 n ( 1 ≤ n ≤ 50 ) n (1 \leq n \leq 50) n(1n50),表示学生的个数,接下来的一行,包含 n 个整数,按顺序表示每个学生的能力值 a i a_i ai − 50 ≤ a i ≤ 50 -50 \leq a_i \leq 50 50ai50)。接下来的一行包含两个整数,k 和 d ( 1 ≤ k ≤ 10 , 1 ≤ d ≤ 50 ) d (1 \leq k \leq 10, 1 \leq d \leq 50) d(1k10,1d50)

输出描述

  • 输出一行表示最大的乘积

输入例子:

3
7 4 7
2 50

输出例子:

49

先修知识:

  • 动态规划: 动态规划表面上很难,其实存在很简单的套路:当求解的问题满足以下两个条件时, 就应该使用动态规划:
  1. 主问题的答案 包含了 可分解的子问题答案 (也就是说,问题可以被递归的思想求解)
  2. 递归求解时, 很多子问题的答案会被多次重复利用
  • 动态规划的本质思想就是递归, 但如果直接应用递归方法, 子问题的答案会被重复计算产生浪费, 同时递归更加耗费栈内存(具体为什么更加消耗栈内存, 需要额外了解函数调用过程中, 进程栈内存的管理方式), 所以通常用一个二维矩阵(表格)来保存不同子问题的答案, 避免重复计算。

题目难点:

  • 元素有正有负
  • 如何满足相邻元素的距离不超过d 的限制

巧妙地分解问题

  • 给定n个元素, 寻找k 个元素使乘积最大,可以从这k 个元素中最后一个元素所在的位置入手来思考。

  • 对于数组 a=【7,4,7】, 假如 k ( 所 需 元 素 个 数 ) k(所需元素个数) k() =2, d ( 相 邻 元 素 的 最 大 编 号 差 ) d(相邻元素的最大编号差) d()=2. 如果假设 a[2] 为目标序列的最后一个元素时, 还需要在a[2] 之前的元素中,寻找到一个长度为 $k-1 $的乘积序列, 且该序列的最后一个元素a[p] 与a[2]的距离小于等于d, 即 2 − p < = d 2-p <=d

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值