LeetCode 每日一题 2140. 解决智力问题 LeetCode你怎么骂人哇QAQ,就算是愚人节也不能原谅(

2140. 解决智力问题

解决俺自己的智力问题先

给你一个下标从 0 开始的二维整数数组 questions ,其中 questions[i] = [pointsi, brainpoweri] 。
这个数组表示一场考试里的一系列题目,你需要 按顺序 (也就是从问题 0 开始依次解决),针对每个问题选择 解决 或者 跳过 操作。解决问题 i 将让你 获得 pointsi 的分数,但是你将 无法 解决接下来的 brainpoweri 个问题(即只能跳过接下来的 brainpoweri 个问题)。如果你跳过问题 i ,你可以对下一个问题决定使用哪种操作。
比方说,给你 questions = [[3, 2], [4, 3], [4, 4], [2, 5]] :
如果问题 0 被解决了, 那么你可以获得 3 分,但你不能解决问题 1 和 2 。
如果你跳过问题 0 ,且解决问题 1 ,你将获得 4 分但是不能解决问题 2 和 3 。
请你返回这场考试里你能获得的 最高 分数。
示例 1:
输入:questions = [[3,2],[4,3],[4,4],[2,5]]
输出:5
解释:解决问题 0 和 3 得到最高分。
-解决问题 0 :获得 3 分,但接下来 2 个问题都不能解决。
-不能解决问题 1 和 2
-解决问题 3 :获得 2 分
总得分为:3 + 2 = 5 。没有别的办法获得 5 分或者多于 5 分。
示例 2:
输入:questions = [[1,1],[2,2],[3,3],[4,4],[5,5]]
输出:7
解释:解决问题 1 和 4 得到最高分。
-跳过问题 0
-解决问题 1 :获得 2 分,但接下来 2 个问题都不能解决。
-不能解决问题 2 和 3
-解决问题 4 :获得 5 分
总得分为:2 + 5 = 7 。没有别的办法获得 7 分或者多于 7 分。
提示:
1 <= questions.length <= 105
questions[i].length == 2
1 <= pointsi, brainpoweri <= 105

题解

看到题目就很显然 能想到需要使用动态规划解题

可以类比经典的打家劫舍

打家劫舍中对于每一家都仅需要考虑偷与不偷两种选择

那么这道题中对于每一道题也仅仅需要考虑做与不做两种选择

打家劫舍中我们通过 max(dp[i−2]+nums[i],dp[i−1]) 记录每一家可以偷的最大值

这道题由于做完一道题目之后需要跳过的题数都不一样,我们无法直接知道抵达某一道题目的全部路径,也就是无法直接写出状态方程

但是每一道题目依旧是仅需要考虑两种选择,跳过或做题

我们可以用数组记录做到题目 question[ i ]时(这道题目还没做)可以得到的最大分数 arr[ i ],对于这道题目

  • 跳过
    那么 arr[ i+1 ] 为 arr[ i ](如果其大于arr[ i+1 ]原有值的话)


  • 那么 arr[ i+1+questions[i][1] ] 为 arr[ i ] + question[ i ][0](如果其大于arr[ i+1+questions[i][1] ]原有值的话)

于是我们可以将arr数组初始化为0,然后遍历数组question,考虑两种情况,维护数组arr,当遍历到 i 时,可以得到的最大分数 (question[ i ]还没做)就为 arr[ i ]

因为做题后只能向后跳,到达 question[ i ] 的所有可能只有前一道题目跳过或者 question[ i ] 之前的题目做之后跳到这个位置,所以在遍历完前面所有题目的可能之后,arr[ i ]内记录的就是可以得到的最大分数 (question[ i ]还没做)

于此同时,我们不断记录做了题目之后得到的分数,即 arr[ i ] + question[ i ][0] 的最大值,其最大值就是返回值


代码如下↓

long long mostPoints(int** questions, int questionsSize, int* questionsColSize) {
    long long arr[questionsSize];
    memset(arr,0,sizeof(arr));
    long long res=0;
    for(int i=0;i<questionsSize;i++)
    {
        long long x=arr[i];
        long long y=arr[i]+questions[i][0];
        if(x>res)
        {
            res=x;
        }
        if(y>res)
        {
            res=y;
        }
        if(i+1<questionsSize && x>arr[i+1])
        {
            arr[i+1]=x;
        }
        if(i+1+questions[i][1]<questionsSize && y>arr[i+1+questions[i][1]])
        {
            arr[i+1+questions[i][1]]=y;
        }
    }
    return res;
}

你可能感兴趣的:(LeetCode题目题解,leetcode,算法,c语言,数据结构)