题目描述
给你一个长度为 n
下标从 0 开始的整数数组 receiver
和一个整数 k
。
总共有 n
名玩家,玩家 编号 互不相同,且为 [0, n - 1]
中的整数。这些玩家玩一个传球游戏,receiver[i]
表示编号为 i
的玩家会传球给编号为 receiver[i]
的玩家。玩家可以传球给自己,也就是说 receiver[i]
可能等于 i
。
你需要从 n
名玩家中选择一名玩家作为游戏开始时唯一手中有球的玩家,球会被传 恰好 k
次。
如果选择编号为 x
的玩家作为开始玩家,定义函数 f(x)
表示从编号为 x
的玩家开始,k
次传球内所有接触过球玩家的编号之 和 ,如果有玩家多次触球,则 累加多次 。换句话说, f(x) = x + receiver[x] + receiver[receiver[x]] + ... + receiver(k)[x]
。
你的任务时选择开始玩家 x
,目的是 最大化 f(x)
。
请你返回函数的 最大值 。
注意:receiver
可能含有重复元素。
示例 1:
传递次数 |
传球者编号 |
接球者编号 |
x + 所有接球者编号 |
|
|
|
2 |
1 |
2 |
1 |
3 |
2 |
1 |
0 |
3 |
3 |
0 |
2 |
5 |
4 |
2 |
1 |
6 |
输入:receiver = [2,0,1], k = 4
输出:6
解释:上表展示了从编号为 x = 2 开始的游戏过程。
从表中可知,f(2) 等于 6 。
6 是能得到最大的函数值。
所以输出为 6 。
示例 2:
传递次数 |
传球者编号 |
接球者编号 |
x + 所有接球者编号 |
|
|
|
4 |
1 |
4 |
3 |
7 |
2 |
3 |
2 |
9 |
3 |
2 |
1 |
10 |
输入:receiver = [1,1,1,2,3], k = 3
输出:10
解释:上表展示了从编号为 x = 4 开始的游戏过程。
从表中可知,f(4) 等于 10 。
10 是能得到最大的函数值。
所以输出为 10 。
提示:
1 <= receiver.length == n <= 105
0 <= receiver[i] <= n - 1
1 <= k <= 1010
解法
方法一:动态规划 + 倍增
题目要我们寻找从每个玩家 $i$ 开始,传球 $k$ 次内所有接触过球玩家的编号之和的最大值。如果暴力求解,需要从 $i$ 开始向上遍历 $k$ 次,时间复杂度为 $O(k)$,显然会超时。
我们可以使用动态规划,结合倍增的思想来处理。
我们定义 $f[i][j]$ 表示从玩家 $i$ 开始,传球 $2^j$ 次所能到达的玩家编号,定义 $g[i][j]$ 表示从玩家 $i$ 开始,传球 $2^j$ 次所能到达的玩家编号之和(不包括最后一个玩家)。
当 $j=0$ 是,传球次数为 $1$,所以 $f[i][0] = receiver[i]$,而 $g[i][0] = i$。
当 $j \gt 0$ 时,传球次数为 $2^j$,相当于从玩家 $i$ 开始,传球 $2^{j-1}$ 次,再从玩家 $f[i][j-1]$ 开始,传球 $2^{j-1}$ 次,所以 $f[i][j] = f[f[i][j-1]][j-1]$,而 $g[i][j] = g[i][j-1] + g[f[i][j-1]][j-1]$。
接下来,我们可以枚举每个玩家 $i$ 作为开始玩家,然后根据 $k$ 的二进制表示,累计向上查询,最终得到玩家 $i$ 开始,传球 $k$ 次内所有接触过球玩家的编号之和的最大值。
时间复杂度 $O(n \times \log k)$,空间复杂度 $O(n \times \log k)$。其中 $n$ 为玩家数。
相似题目:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | class Solution:
def getMaxFunctionValue(self, receiver: List[int], k: int) -> int:
n, m = len(receiver), k.bit_length()
f = [[0] * m for _ in range(n)]
g = [[0] * m for _ in range(n)]
for i, x in enumerate(receiver):
f[i][0] = x
g[i][0] = i
for j in range(1, m):
for i in range(n):
f[i][j] = f[f[i][j - 1]][j - 1]
g[i][j] = g[i][j - 1] + g[f[i][j - 1]][j - 1]
ans = 0
for i in range(n):
p, t = i, 0
for j in range(m):
if k >> j & 1:
t += g[p][j]
p = f[p][j]
ans = max(ans, t + p)
return ans
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | class Solution {
public long getMaxFunctionValue(List<Integer> receiver, long k) {
int n = receiver.size(), m = 64 - Long.numberOfLeadingZeros(k);
int[][] f = new int[n][m];
long[][] g = new long[n][m];
for (int i = 0; i < n; ++i) {
f[i][0] = receiver.get(i);
g[i][0] = i;
}
for (int j = 1; j < m; ++j) {
for (int i = 0; i < n; ++i) {
f[i][j] = f[f[i][j - 1]][j - 1];
g[i][j] = g[i][j - 1] + g[f[i][j - 1]][j - 1];
}
}
long ans = 0;
for (int i = 0; i < n; ++i) {
int p = i;
long t = 0;
for (int j = 0; j < m; ++j) {
if ((k >> j & 1) == 1) {
t += g[p][j];
p = f[p][j];
}
}
ans = Math.max(ans, p + t);
}
return ans;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 | class Solution {
public:
long long getMaxFunctionValue(vector<int>& receiver, long long k) {
int n = receiver.size(), m = 64 - __builtin_clzll(k);
int f[n][m];
long long g[n][m];
for (int i = 0; i < n; ++i) {
f[i][0] = receiver[i];
g[i][0] = i;
}
for (int j = 1; j < m; ++j) {
for (int i = 0; i < n; ++i) {
f[i][j] = f[f[i][j - 1]][j - 1];
g[i][j] = g[i][j - 1] + g[f[i][j - 1]][j - 1];
}
}
long long ans = 0;
for (int i = 0; i < n; ++i) {
int p = i;
long long t = 0;
for (int j = 0; j < m; ++j) {
if (k >> j & 1) {
t += g[p][j];
p = f[p][j];
}
}
ans = max(ans, p + t);
}
return ans;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 | func getMaxFunctionValue(receiver []int, k int64) (ans int64) {
n, m := len(receiver), bits.Len(uint(k))
f := make([][]int, n)
g := make([][]int64, n)
for i := range f {
f[i] = make([]int, m)
g[i] = make([]int64, m)
f[i][0] = receiver[i]
g[i][0] = int64(i)
}
for j := 1; j < m; j++ {
for i := 0; i < n; i++ {
f[i][j] = f[f[i][j-1]][j-1]
g[i][j] = g[i][j-1] + g[f[i][j-1]][j-1]
}
}
for i := 0; i < n; i++ {
p := i
t := int64(0)
for j := 0; j < m; j++ {
if k>>j&1 == 1 {
t += g[p][j]
p = f[p][j]
}
}
ans = max(ans, t+int64(p))
}
return
}
|