# 【备战秋招】每日一题:4月8日美团春招第三题:题面+题目思路 + C++/python/js/Go/java带注释

#### 样例

6 4 3
1 4 5 1 4 1

21

### 思路

#### 类似题目推荐

LeetCode

132. 分割回文串 II - 一样是在序列上枚举最后一段的情况的动态规划

CodeFun2000

P1178 小红书 2023.04.09-春招-第二题-融合试剂

P1142. 网易有道 2023.4.2-研发岗-第一题-最长k阶完美子序列

P1149 2023.03.30-第一题-塔子哥玩游戏

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]); // 输出结果
});
• 0
点赞
• 0
收藏
觉得还不错? 一键收藏
• 打赏
• 0
评论
02-27 9875
05-01 3031
04-13 6277
05-19 1万+
05-20 357
05-16 261
05-18 678
05-16 621

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

¥1 ¥2 ¥4 ¥6 ¥10 ¥20

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