leetcode每日一题day1(24.9.11)——两个线段获得的最多奖品


思路分析:同样的题如果是找一个段使奖品最多就很好求解,

        对上述情况进行展开:使用滑动窗口对数组中每个长为k的段进行求和算出最多的一个,流程大致为先计算下标0->k-1的和,然后往后加data[k]-data[1], 由一个记录变量来记录当前值和前面所有情况的最大值较大的一个。

上面已经知道一个段怎么找了,但我们需要的是两个段,如何把情况约束成上面情况呢,

        分析:设想如果直接假定第二个段的位置为Left->Left+k,这样子是不是就能把第一个段约束在下标0-Left-1内呢,现在第一个段就可以当成处理完毕了(利用滑动窗口),假定的位置,既然是假定当然应该考虑所有情况即取0->ksize-k-1->size-1都应考虑到。

接下来就是可行性的考量

        质疑起点

                对于第二个段理论上肯定是可以取0的,即总共就k个数据的情况,往后都是给第一段留了“余地”的的情况,毋庸置疑也是可行的。

        质疑k

                那有没有可能第二个段取不到k个呢,例如当k=1,此时一个线段可以拿两个点的礼物,最多的是倒数第三个和倒数第二个 然后是倒数第一个最多, 显然也是不可能的,最后三个最多的话,此时完全可以取后四个(第一段取倒三倒四,第二段取倒一倒二)多一个倒四完全正受益,其他情况同理

理论成立

        利用一个一维数组存储,要是当前位置是第二个段的起点Left时,第一个段能拿的最大值,考虑细节进行编码,参考leetcode官方题解进行了优化(官方真细)

代码

class Solution {
public:
    int maximizeWin(vector<int>& prizePositions, int k) {
        int size=prizePositions.size(),res=0;
        vector<int> dp(size+1);
        for(int l=0,r=0;r<=size-1;r++){
            while(prizePositions[r]-prizePositions[l]>k){l++;}
            res=max(dp[l]+r-l+1,res);
            dp[r+1]=max(dp[r],r-l+1);
        }
        return res;
    }
};

结语:分析阶段 大胆猜想 小心求证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值