在传球游戏中最大化函数值

给你一个长度为 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;
    }
};
posted @ 2023-08-28 16:23  失控D大白兔  阅读(6)  评论(0编辑  收藏  举报