首页 > 其他分享 >平衡子序列的最大和

平衡子序列的最大和

时间:2023-11-06 11:46:03浏览次数:459  
标签:最大 nums int res vector 序列 平衡

给你一个下标从 0 开始的整数数组 nums 。
nums 一个长度为 k 的 子序列 指的是选出 k 个 下标 i0 < i1 < ... < ik-1 ,如果这个子序列满足以下条件,我们说它是 平衡的 :
对于范围 [1, k - 1] 内的所有 j ,nums[i] - nums[j] >= i - j 都成立。
nums 长度为 1 的 子序列 是平衡的。
请你返回一个整数,表示 nums 平衡子序列里面的最大元素和 。

1. 离散化树状数组

树状数组求左侧闭区间最大值

class Solution {
public:
    vector<long long> tree;
    int idx = 1;
    long long maxBalancedSubsequenceSum(vector<int>& nums) {
        //要满足nums[i]-nums[j]>=i-j
        //即满足nums[i]-i>=nums[j]-j,子序列满足该值的升序
        int n = nums.size();
        vector<int> val(n);
        map<int,int> m;//离散化优先顺序
        for(int i=0;i<n;i++){
            val[i] = nums[i]-i;
            m[val[i]]++;
        }
        for(auto &[k,v]:m)
            v = idx++;
        for(auto &v:val)
            v = m[v];//用优先级替换数值

        tree.resize(idx+1,INT_MIN);
        long long res = INT_MIN;
        for(int i=0;i<n;i++){//找满足val更小的最大值
            int p = val[i];
            //找小于等于p的最大值
            long long premax = getmax(p);
            long long cur = premax+nums[i];
            res = max(res,cur);
            updata(p,cur);
        }
        return res;
    }

    int lowbit(int x){//求二进制化最后一位的值
        return x&(-x);
    }
    void updata(int i,long long k){ //
        while(i<=idx){//更新子树上所有值
            tree[i] = max(tree[i],k);
            i+=lowbit(i);//移动到父亲节点
        }
    }

    long long getmax(int i){  //求数组前i项的和
        long long res = 0;//比0大才加上
        while(i>0){//O(logn)求前缀和
            res = max(res,tree[i]);
            i-=lowbit(i);//移动到前一棵子树(子区间)
        }
        return res;
    }
};

标签:最大,nums,int,res,vector,序列,平衡
From: https://www.cnblogs.com/929code/p/17812303.html

相关文章

  • java数组最大值
    参考文章:java数组求最大值在Java中,你可以通过遍历数组元素来找到数组中的最大值。以下是两种常见的方法:使用循环遍历数组publicclassMain{publicstaticvoidmain(String[]args){int[]array={10,5,8,2,7};//假设数组的第一个元素是最大......
  • 最大公约数
    最大公约数目录最大公约数辗转相除法伪代码null辗转相除法https://zhuanlan.zhihu.com/p/324578532欧几里得算法又称辗转相除法,是指用于计算两个非负整数a,b的最大公约数。应用领域有数学和计算机两个方面。计算公式gcd(a,b)=gcd(b,amodb)。两个整数的最大公约数是能......
  • 求最大公约数伪代码
    欧几里得算法欧几里得算法又称辗转相除法,是指用于计算两个非负整数a,b的最大公约数。计算方法:gcd(a,b)=gcd(b,amodb)(不妨设a>b且r=amodb,r不为0)其中gcd指最大公约数,mod指取模运算(因为操作数为正数,看成取余),伪代码里取余写作REMhttps://baike.baidu.com/item/%E6%AC%A......
  • 求最大公约数伪代码
    求最大公约数伪代码1.上网查找什么是求两个数的最大公约数的欧几里得算法(辗转相除法),提交算法说明和网上链接。欧几里得算法(辗转相除法)是求两个数的最大公约数的经典算法。其基本思想是:用较大的数除以较小的数,然后用余数作为新的被除数,继续进行操作,直到余数为0,此时的除数即为最......
  • 求最大公约数伪代码(课下测试,必做)
    1.上网查找什么是求两个数的最大公约数的欧几里得算法(辗转相除法),提交算法说明和网上链接。欧几里得算法又称辗转相除法,是指用于计算两个非负整数a,b的最大公约数。应用领域有数学和计算机两个方面。计算公式gcd(a,b)=gcd(b,amodb)。两个整数的最大公约数是能够同时整除它们......
  • Prüfer 序列随便学习
    引入首先这是个啥玩意呢?Prüfer序列可以将带标号的\(n\)个节点的树用一个序列表示。可以理解为完全图生成树与Prüfer序列构建了双射。建立每次选择一个编号最小的叶结点并删掉它,然后在序列中记录下它连接到的那个结点。重复\(n-2\)次后就只剩下两个结点,算法结束。......
  • 求最大公约数伪代码
    什么是欧几里得算法辗转相除法,又名欧几里德算法(Euclideanalgorithm),是求最大公约数的一种方法。它的具体做法是:用较大数除以较小数,再用出现的余数(第一余数)去除除数,再用出现的余数(第二余数)去除第一余数,如此反复,直到最后余数是0为止。如果是求两个数的最大公约数,那么最后的除数就......
  • LeetCode/在树上执行操作以后得到的最大分数
    有一棵n个节点的无向树,节点编号为0到n-1,根节点编号为0。给你一个长度为n-1的二维整数数组edges表示这棵树,其中edges[i]=[ai,bi]表示树中节点ai和bi有一条边。同时给你一个长度为n下标从0开始的整数数组values,其中values[i]表示第i个节点的值......
  • 用欧几里得算法求两个数的最大公约数
    一.什么是欧几里得算法1.欧几里得算法就是辗转相除法,用于求两个数的最大公约数。如果用gcd(a,b)表示a和b的最大公约数,gcd(a,b)=gcd(b,a%b),当a%b==0时,b就是最大公约数。2.算法说明:首先按照大小输入两个整数a、b,再用一个中间量用来存放二者的余数。计算后将b的值赋给a,将余数赋给b......
  • 基于时间序列联动分析的补货与定价策略研究
    IntroductionThisisanexcellentpaperofmathematicalmodelingresearchwiththehonourofNationalSecondPrize(<2.3%).ResearchonReplenishmentandPricingStrategiesBasedonTimeSeriesLinkageAnalysisZhihaoLi,PaiLin,KaidaHuangChinaUn......