目录
一、顺丰笔试第二题(2023.9.27)
题目描述:
总共有N个员工,每个员工都有其对应的能力值。每个任务有一个对应的难度M。现在要将N个员工进行分组,假设某一组有K个员工,如果
,Amax表示改组员工能力的最大值,那么该组员工能够完成该任务。问最多能将N分成几组?
输入:
5 100
37 43 55 82 121
输出:
3
解释:{[121], [82,37], [55, 43]}
解题思路:
首先对能力值数组进行正序排序,然后从末尾开始遍历。
主要使用贪心思想,判断该职工的能力值是否大于M的难度值,如果大于,则分组数量加一;如果小于,那就判断其加一个能力值较小的组员是否能完成,如果不行,再加一个组员,直到人数乘以该组员的能力值大于任务难度值M。同时这里要判断好人数,也就是说当你加了一个人之后,对应的可选人数就要减少一个。
代码
package main
import (
"fmt"
"sort"
)
func main() {
var n, m int
fmt.Scan(&n, &m)
ability := make([]int, n)
for i := 0; i < n; i++ {
fmt.Scan(&ability[i])
}
sort.Ints(ability)
total := 0
k := 2
nums := n
for j := n - 1; j >= 0; j-- {
if ability[j] >= m {
total++
nums = nums - total
} else {
for nums-k >= 0 {
if ability[j]*k >= m {
total++
nums -= k
break
} else {
k++
}
}
}
}
fmt.Println(total)
}
二、建信金科第二题(2023.11.4)
题目描述:
小红随机选择链表中的一个节点,删除该节点和该节点的前后两个节点,问删除所有节点所需操作次数的期望。
输入:
3
4
输出:
1.666666666666666
2
解题思路:
方法一:暴力搜索
删除链表所需次数的期望,就是平均需要多少次才能把链表删掉。因此暴力的思路就很简单:
使用DFS,求出所有可能的删除路径,并且求出每种删除方式需要所需要的删除次数,把这些次数相加除以所有可能的删除路径的数量,就是最后的期望
方法二:动态规划
dp[n]:表示删除n个节点所需要删除次数的期望
递推公式:dp[i] = 2/i * (1 + dp[i-2]) + (n-2)/i * (1 + dp[i-3])
链表中删除节点有两种可能,一种是删除头或者尾节点,另外一种就是删除中间节点,所以选择头或者尾节点的概率为 2 / i;选择中间节点的概率为 i-2 / i。当选择了头或者尾节点,那么就需要dp[i-2]的期望加一就等于选择了该节点时所需要的次数。选择中间节点同理。
初始化:dp[0]=0;dp[1] = 1;dp[2] = 1
代码:
func main() {
n := 0
fmt.Scan(&n)
dp := make([]float64, n+1)
dp[0] = 0
dp[1] = 1
dp[2] = 1
for i := 3; i <= n; i++ {
dp[i] = float64(2)/float64(i)*(dp[i-2]+1) + float64(i-2)/float64(i)*(dp[i-3]+1)
}
fmt.Println(dp)
}