2023大厂笔试模拟练习网站(含题解)
www.codefun2000.com
最近我们一直在将收集到的各种大厂笔试的解题思路还原成题目并制作数据,挂载到我们的OJ上,供大家学习交流,体会笔试难度。现已录入200+道互联网大厂模拟练习题,还在极速更新中。欢迎关注公众号“塔子哥学算法”获取最新消息。
提交链接:
https://codefun2000.com/p/P1138
为了更好的阅读体检,可以查看OJ上的题解。进入提交链接,点击右边菜单栏的"查看塔子哥的题解"
题目内容
塔子哥开的玩具店生意越来越好,每天都有很多客人前来选购玩具。有一天,他接到了一个大单,客户想购买 n 个玩具,并且要求打包成多个玩具袋。塔子哥精心为客户挑选了 n 个玩具,并且将它们编号为 1,2,,n。
然而,塔子哥发现这个订购单还有一个要求:每个玩具袋最多只能装 m 个玩具,并且同一个玩具袋里装的玩具编号必须是连续的。玩具袋的成本与容积成线性关系。
为了解决这个问题,他决定采用样本中点估计的方法来计算玩具袋的容积。具体来说,如果一个玩具袋中装的最大的玩具容积是 u,最小的是 v,那么这个玩具袋的成本就是 k \times floor((u+v)/2) +s,其中 k 是玩具袋中装入玩具的个数,s 是一个常数, floor(x) 是下取整函数,比如 floor(3.8)=3 , floor(2)=2
客户并没有规定玩具袋的数量,但是希望玩具袋的成本越小越好,毕竟买玩具就很贵了。请求出塔子哥打包这 n 个玩具所用的最小花费。
输入描述
第一行三个正整数 n,m,s 。意义如题面所示
第二行 n 个正整数 ,,..., ,表示每个玩具的体积。
对于全部数据, , , , 。
输出描述
输出一个整数,表示打包这 n 个玩具玩具袋的最小成本。
样例
输入
6 4 3 1 4 5 1 4 1
输出
21
样例解释
前三个玩具装成一个玩具袋,后三个玩具装成一个玩具袋。
思路
序列上的动态规划
状态
表示将前 i 个玩具装入玩具袋中的最小花费。
转移
解题关键:
考虑枚举最后一个玩具袋的玩具个数:1个,2个,...,m个。确定好最后一个玩具袋的情况,我们能够划归成子问题。故状态转移方程为:
其中 和
时间复杂度:O(nm)
类似题目推荐
LeetCode
132. 分割回文串 II - 一样是在序列上枚举最后一段的情况的动态规划
CodeFun2000
P1178 小红书 2023.04.09-春招-第二题-融合试剂
P1142. 网易有道 2023.4.2-研发岗-第一题-最长k阶完美子序列
P1151. 拼多多 2023.03.30-第三题-乘积最大的连续子数组
代码
CPP
#include <bits/stdc++.h> using namespace std; const int N = 10010, M = 1010; int a[N], n, m, s; int dp[N]; int main() { scanf("%d%d%d", &n, &m, &s); for (int i = 1; i <= n; ++i) { scanf("%d", &a[i]); } // dp[i] 表示将前 i 个玩具打包的最小权值 memset(dp, 0x3f, sizeof dp); dp[0] = 0; for (int i = 1; i <= n; ++i) { int maxv = a[i], minv = a[i]; // 枚举最后一段 for (int j = i - 1; j >= max(0, i - m); --j) { dp[i] = min(dp[i], dp[j] + ((minv + maxv) / 2 * (i - j) + s)); minv = min(minv, a[j]); maxv = max(maxv, a[j]); } } printf("%d\n", dp[n]); return 0; }
python
n, m, s = map(int, input().split(" ")) a = list(map(int, input().split(" "))) #dp[i] 表示将前 i 个玩具打包的最小权值 dp = [0x3f3f3f3f] * (n + 1) dp[0] = 0 for i in range(1, n + 1): minv, maxv = a[i - 1], a[i - 1] # 枚举最后一段 for j in range(i - 1, max(-1, i - m - 1), -1): dp[i] = min(dp[i], dp[j] + ((minv + maxv) // 2 * k + s)) if j > 0: minv = min(minv, a[j - 1]) maxv = max(maxv, a[j - 1]) print(dp[n])
Java
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int m = sc.nextInt(); int s = sc.nextInt(); int[] a = new int[n + 1]; for (int i = 1; i <= n; ++i) { a[i] = sc.nextInt(); } // dp[i] 表示将前 i 个玩具打包的最小权值 int[] dp = new int[n + 1]; dp[0] = 0; for (int i = 1; i <= n; ++i) dp[i] = 0x3f3f3f3f; for (int i = 1; i <= n; ++i) { int maxv = a[i], minv = a[i]; // 枚举最后一段 for (int j = i - 1; j >= Math.max(0, i - m); --j) { dp[i] = Math.min(dp[i], dp[j] + (minv + maxv) / 2 * (i - j) + s); minv = Math.min(minv, a[j]); maxv = Math.max(maxv, a[j]); } } System.out.println(dp[n]); } }
Go
package main import ( "fmt" ) func main() { var n, m, s int fmt.Scan(&n, &m, &s) a := make([]int, n) for i := 0; i < n; i++ { fmt.Scan(&a[i]) } // dp[i] 表示将前 i 个玩具打包的最小权值 dp := make([]int, n+1) for i := range dp { dp[i] = 0x3f3f3f3f } dp[0] = 0 for i := 1; i <= n; i++ { minv, maxv := a[i-1], a[i-1] // 枚举最后一段 for j := i - 1; j > max(-1, i-m-1); j-- { mid := (minv + maxv) / 2 dp[i] = min(dp[i], dp[j]+(mid*(i - j))+s) if j > 0 { minv = min(minv, a[j-1]) maxv = max(maxv, a[j-1]) } } } fmt.Println(dp[n]) } func min(a, b int) int { if a < b { return a } return b } func max(a, b int) int { if a > b { return a } return b }
Js
process.stdin.resume(); process.stdin.setEncoding('utf-8'); let input = ''; process.stdin.on('data', (data) => { input += data; }); process.stdin.on('end', () => { const lines = input.trim().split('\n'); const [n, m, s] = lines[0].split(" ").map(Number); // 解构出n,m,s并转为数字类型 const a = lines[1].split(" ").map(Number); // 将 a 数组转为数字类型 // dp[i] 表示将前 i 个玩具打包的最小权值 const dp = new Array(n + 1).fill(0x3f3f3f3f); dp[0] = 0; for(let i = 1; i <= n; i++) { let [minv, maxv] = [a[i - 1], a[i - 1]]; // 枚举最后一个玩具袋的情况 for(let j = i - 1; j > Math.max(-1, i - m - 1); j--) { dp[i] = Math.min(dp[i], dp[j] + ((Math.floor((minv + maxv) / 2)) * (i - j) + s)); if(j > 0) { minv = Math.min(minv, a[j - 1]); maxv = Math.max(maxv, a[j - 1]); } } } console.log(dp[n]); // 输出结果 });