力扣第 104 场双周赛 2681. 英雄的力量

原题链接力扣

 题目大意:我开始看成连续子段了,写了个递归程序....... 

一个数组任选一个子序列,子序列的力量值=最大值平方*最小值。求所有子序列的力量和。

分析过程:如序列长度为n,子序列总数为2的n次幂,显然不可能枚举所有子序列来求解。那么只能锁定子序列最大值和最小值来处理。容易想到先排序,排序后的序列可以取任意ai和aj,那么ai最小值,aj 最大值,i和j之间的元素可以任取,例如i=2,j=6,那么i和j之间有3个其他元素,这3个元素可以任取,因此共有2的3次幂共8种选取方法:(a2,a6) (a2,a3,a6) (a2,a4,a6) (a2,a5,a6)(a2,a3,a4,a6).......。枚举所有i和j,时间复杂度为O(n2)。

这类问题如何继续降低复杂度。一般来说都会存在某种规律,使得下一次的处理能利用上一次的结果,也有写问题存在某种(数学)方法,能直接求得解。本题目通过找规律解决。

假设a1为最小值,那么子序列中必然有a1,此时如果锁定ai为最大值,那么所有满足(a1最小,ai最大)的子序列数量必然ai*ai*a1*pow(2,i-2)。

枚举下最大最小值分别为(i,j)的公式

最大值j\最小值ia1       a2a3......总和
a2a1*a2*a2

(a1)*a2*a2

a32a1*a3*a3a2*a3*a3

(2a1+a2)*a3*a3

a44a1*a4*a42a2*a4*a4(4a1+2a2+a3)*a4*a4
a58a1*a5*a54a2*a5*a52a3*a5*a5......(8a1+4a2+2a3+a4)*a5*a5
a616a1*a6*a68a2*a6*a64a3*a6*a6......

可以发现规律为当ai为最大值时,其组成所有子序列的力量和为Y[i]*a[i]*a[i],而这个Y[i]可以由Y[i-1]*2+a[i-1]求得。

class Solution {
public:
    int sumOfPower(vector<int>& nums) {
        int i,j,r=nums.size()-1,mod=1e9+7;;
        sort(nums.begin(),nums.end());/**< 排序 */
        long long ans=0,sum=nums[0];
        for(i=0;i<=r;i++)/**< 就一个元素序列单独处理 */
            ans=(ans+1LL*nums[i]*nums[i]%mod*nums[i])%mod;
        for(i=1;i<=r;i++)/**< 最大值为i的力量和 */
        {
            long long temp=1LL*nums[i]*nums[i]%mod;
            ans=(ans+temp*sum%mod)%mod;
            sum=(sum*2+nums[i])%mod;/**< i+1的系数 */
        }
        return (int)ans;
    }
};

两个循环综合在一起的写法。

class Solution {
public:
    int sumOfPower(vector<int>& nums) {
        int i,j,r=nums.size()-1,mod=1e9+7;;
        sort(nums.begin(),nums.end());/**< 排序 */
        long long ans=0,sum=0;
        for(i=0;i<=r;i++)/**< 最大值为i的力量和 */
        {
            long long temp=1LL*nums[i]*nums[i]%mod;
            ans=(ans+temp*(sum+nums[i])%mod)%mod;
            sum=(sum*2+nums[i])%mod;/**< i+1的系数 */
        }
        return (int)ans;
    }
};

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值