青训营X豆包MarsCode 技术训练营刷题记录 | 豆包MarsCode AI 刷题

41 阅读4分钟

问题描述

 

小F正在开发一个推荐系统,该系统使用多个模型来预估不同的目标指标(如点击率和观看时长)。为了有效地融合这些指标,系统对每个目标提供了两种不同的变换方式,每种方式会产生一个变换值。小F的任务是为每个目标选择其中一种变换方式,然后将所有选中的变换值相乘,得到最终的融合结果。

 

然而,不同的选择组合可能会导致最终结果值过大或过小。因此,小F希望计算出在给定的合理区间 [L,R][L,R] 内,有多少种不同的选择组合可以使最终的融合结果落在这个区间内。

 

输入说明

 

  •   n:目标指标的数量

  •   f:一个二维数组,其中 f[i] 表示第 i 个目标的两种变换值

  •   L:期望结果的下界

  •   R:期望结果的上界

 

取值范围

 

  •   1 ≤ n ≤ 20

  •   1 ≤ f[i][j] ≤ 10^9

  •   1 ≤ L ≤ R ≤ 10^9

 

输出说明

 

输出一个整数,表示使最终融合结果落在区间 [L,R][L,R] 内的选择组合数量。

 

测试样例

 

样例1:

 

输入:n = 2, f = [[1, 2], [3, 4]], L = 1, R = 6  

输出:3

 

样例2:

 

输入:n = 2, f = [[1, 2], [3, 4]], L = 4, R = 6  

输出:2

 

样例3:

 

输入:n = 3, f = [[1, 2], [3, 5], [2, 4]], L = 10, R = 50  

输出:7

 

示例说明

 

  1.  在样例1中,有两个目标指标(n=2),可能的选择组合有:

 

    -   1 * 3 = 3(在区间[1, 6]内)

    -   1 * 4 = 4(在区间[1, 6]内)

    -   2 * 3 = 6(在区间[1, 6]内)

    -   2 * 4 = 8(不在区间[1, 6]内)  

        因此,有3种有效的选择组合。

 

  1.  在样例2中,只有两种组合落在区间[4, 6]内:

 

    -   1 * 4 = 4

    -   2 * 3 = 6

 

  1.  在样例3中,有7种组合使得结果落在区间[10, 50]内。

 

要解决这个问题,首先我们需要理解题目中的要求:我们有 n 个目标,每个目标有两种变换值,通过选择不同的变换值来构造一个最终的融合结果。最终的融合结果是通过将每个目标选择的变换值相乘得到的。问题的核心是计算有多少种组合的选择,使得最终结果落在给定的区间 [L, R] 内。

 

思路

 

  1.  暴力搜索:问题要求我们枚举所有可能的选择组合来计算融合结果,并统计其中落在区间 [L, R] 内的结果。

  2.  可能的组合: 对于每个目标 i,我们可以选择变换值 f[i][0]f[i][1],因此每个目标有两种选择。总的选择组合数是 2^n,对于 n <= 20,最多有 1048576(2^20)种选择,这个数量是可以在合理的时间内穷举的。

  3.  计算融合结果: 对每一种选择组合,我们需要计算出所有选择的变换值的乘积,并检查该乘积是否在区间 [L, R] 内。

  4.  优化:考虑到可能出现数值过大或过小的情况,我们需要对乘积进行合适的检查,防止溢出或者无意义的计算。

 

解法

 

我们可以使用位运算来枚举所有的选择组合,每个目标有两种选择,通过二进制表示来标记每个目标选择的变换值。然后计算每种组合的乘积,检查它是否在区间 [L, R] 内。

 

代码实现

 


def solution(n, f, L, R):

    count = 0

    # 枚举所有可能的选择组合,共有2^n种组合

    for mask in range(1 << n):  # 2^n种选择组合

        product = 1

        for i in range(n):

            if mask & (1 << i):  # 如果mask的第i位为1,选择f[i][1]

                product *= f[i][1]

            else:  # 否则选择f[i][0]

                product *= f[i][0]

            # 如果乘积已经超过了R,提前结束

            if product > R:

                break

        if L <= product <= R:

            count += 1

    return count

 

if __name__ == "__main__":

    # 测试用例

    print(solution(3, [[1, 2], [3, 4], [1, 6]], 1, 100))  # 输出:3

 

解释

 

  1.  位运算mask 是一个从 02^n - 1 的整数,表示一个选择组合。对于每个目标 i,如果 mask 的第 i 位为 1,则表示我们选择 f[i][1],否则选择 f[i][0]。通过 mask 可以穷举所有的选择组合。

  2.  乘积计算:对于每个选择组合,我们计算所有目标选择的变换值的乘积。每当计算出一个乘积时,立即检查它是否在区间 [L, R] 内,如果是,则计数。

  3.  提前结束:如果乘积在计算过程中大于 R,我们可以提前结束当前组合的计算,避免不必要的计算。

  4.  边界处理:在最后,我们检查乘积是否在 [L, R] 内,如果是,则增加计数。