在传球游戏中最大化函数值
给你一个长度为 n 下标从 0 开始的整数数组 receiver 和一个整数 k
总共有 n 名玩家,玩家 编号 互不相同,且为 [0, n - 1] 中的整数。
你需要从 n 名玩家中选择一名玩家作为游戏开始时唯一手中有球的玩家,球会被传 恰好 k 次
定义函数 f(x) 表示从编号为 x 的玩家开始,k 次传球内所有接触过球玩家的编号之和
选择开始玩家x ,目的是最大化 f(x)
1. 倍增优化
由于k值过大,这里需要使用倍增优化进行查询
class Solution {
public:
long long getMaxFunctionValue(vector<int>& a, long long k) {
int n = a.size();
int f[n][36]; //f[i][j]表示从i位置跳2的j次方,能到达的位置
long long w[n][36]; //记录从i位置开始,传送2的j次方的累计权值
for(int i = 0; i < n; ++i) {
f[i][0] = a[i];
w[i][0] = i;
}
for(int j = 1; j < 36; ++j) { //一层一层的倍增
for(int i = 0; i < n; ++i) {//遍历一趟
f[i][j] = f[f[i][j-1]][j-1]; //连续跳两次
w[i][j] = w[i][j-1] + w[f[i][j-1]][j-1]; //跳两趟的累计权值
}
}
long long res = 0;
for(int i = 0; i < n; ++i) {//枚举每个位置作为起点
long long cur = 0;
int pos = i;
for(int j = 0; j < 36; ++j) {//将k拆分,进行对数时间复杂度查询
if((k >> j) & 1) {
cur += w[pos][j];
pos = f[pos][j];
}
}
res = max(res, cur + pos);
}
return res;
}
};