当前位置: 首页 > article >正文

AI刷题-融合目标计算问题

目录

问题描述

输入格式

输出格式

输入样例

样例 1

样例 2

输出样例

样例 1

样例 2

数据范围

解题思路: 

问题理解

数据结构选择

算法步骤

代码实现:

 1.单独写一个函数来查找数组中第一个不小于给定值的数:

 2.单独写一个函数来生成所有可能的结果:

举个例子:

3.在组合完成之后,就是通过二分进行筛选 

最后:

最终代码:

运行结果: 


问题描述

在推荐系统中,对于一件物品会使用若干模型预估若干个目标,如点击率,观看时长等,然后将这些目标结合起来形成一套融合公式并以此来给出推荐物品的序。
小茗同学最近对融合公式很感兴趣,为每个预估目标设计了 2 种变换形式,每种形式输出一个变换值。小茗同学需要从 2 种变换形式中选择 1 种合并进融合公式中。出于简化系统的考虑,小茗同学将各种预估目标转换值连续相乘作为融合公式的输出值。
然而,小茗同学只考虑了单个预估目标变换值的值域,导致最后的融合公式可能会输出非常小或非常大的数值。从可维护性和便于统计的角度来说,小茗同学希望融合公式的输出值尽可能“合理”,更具体地,小茗同学需要统计融合公式输出值在[L,R]中的方案数。
小茗同学还有其他的工作,需要你来帮助他完成这项统计。

输入格式

  • 第一行为一个整数 N(2≤N≤40)N(2≤N≤40),表示预估目标的数量。
  • 第 2 行至第 N+1 行,每行两个整数 fi,1,fi,2(1≤fi,1,fi,2≤109)fi,1​,fi,2​(1≤fi,1​,fi,2​≤109),表示小茗同学为第 i 个目标设计的两种变换形式输出值。
  • 第 N+2 行包含两个整数 L,R(0≤L≤R≤1018)L,R(0≤L≤R≤1018),表示融合公式值的统计范围。

输出格式

输出一个整数,表示融合公式统计范围内的方案数。

输入样例

样例 1

2  
1 2  
3 4  
1 6  

样例 2

2  
1 2  
3 4  
4 6  

输出样例

样例 1

3

样例 2

2

数据范围

  • 45% 数据:2≤N≤202≤N≤20;
  • 100% 数据:2≤N≤402≤N≤40。

解题思路: 

问题理解

你有一个推荐系统,其中每个物品有多个预估目标,每个目标有两种变换形式,每种形式输出一个变换值。你需要从每种目标的两种变换形式中选择一种,将所有选择的变换值相乘,得到一个融合公式的输出值。你需要统计这些输出值在给定范围 [L, R] 内的方案数。

数据结构选择

  • 输入数据:你需要存储每个目标的两种变换值,可以使用二维数组或向量来存储。
  • 输出数据:你需要统计满足条件的方案数,最终输出一个整数。

算法步骤

  1. 输入处理:读取输入数据,包括目标数量 N、每个目标的两种变换值、以及范围 [L, R]
  2. 生成所有可能的组合:由于每个目标有两种选择,总共有 2^N 种组合。你可以使用递归或迭代的方式生成所有可能的组合。
  3. 计算每种组合的乘积:对于每种组合,计算所有选择的变换值的乘积。
  4. 统计满足条件的组合:检查每种组合的乘积是否在 [L, R] 范围内,如果是,则计数加一。
  5. 输出结果:输出满足条件的组合数。

代码实现:

 1.单独写一个函数来查找数组中第一个不小于给定值的数:

int bisect_left(const vector<long long>& arr, long long x) {
    return lower_bound(arr.begin(), arr.end(), x) - arr.begin();
}

 2.单独写一个函数来生成所有可能的结果:

 

vector<long long> gen(const vector<vector<int>>& a) {
    int n = a.size();
    vector<long long> b;
    for (int st = 0; st < (1 << n); ++st) {
        long long m = 1;
        for (int i = 0; i < n; ++i) {
            m *= a[i][(st >> i) & 1];
        }
        b.push_back(m);
    }
    sort(b.begin(), b.end());
    return b;
}

对于整个外循环来说,需要进行2^n次循环,也就是:

 

st < (1 << n)

 而内循环则是进行组合,

  • 对于每个组合 st,内层循环遍历每个目标指标 i
  • (st >> i) & 1 用于判断当前组合 st 中第 i 个目标指标是否被选中(即二进制表示中第 i 位是否为 1)。
  • 如果选中,则乘以对应的变换值 a[i][1],否则乘以 a[i][0]

举个例子:

假设 n = 2a = [[1, 2], [3, 4]],那么 st 的取值范围是 0 到 3(即 00011011):

  • 当 st = 000):
    • m = 1 * 1 * 3 = 3
  • 当 st = 101):
    • m = 1 * 2 * 3 = 6
  • 当 st = 210):
    • m = 1 * 1 * 4 = 4
  • 当 st = 311):
    • m = 1 * 2 * 4 = 8

因此,向量 b 中会存储 [3, 6, 4, 8]

 

3.在组合完成之后,就是通过二分进行筛选 

int ans = 0;
	++R;
	for (long long x : u) {
		ans += bisect_left(v, (R + x - 1) / x) - bisect_left(v, (L + x - 1) / x);
	}

 

 (R + x - 1) / x和L + x - 1) / x 就是简单的向上取整,用函数反正是一样的

调用函数也就是为了找到大于等于R / x和L / x的值,然后二者相减 

最后:
  • 通过计算这两个二分查找结果的差值,我们可以得到所有使得 L <= v[i] * x <= R 的 v[i] 的数量。
  • 这个差值表示在区间 [L, R] 内的有效组合数量,并将其累加到 ans 中。

至此也就实现了题目要求 

最终代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>

using namespace std;

int bisect_left(const vector<long long>& arr, long long x) {
    return lower_bound(arr.begin(), arr.end(), x) - arr.begin();
}

vector<long long> gen(const vector<vector<int>>& a) {
    int n = a.size();
    vector<long long> b;
    for (int st = 0; st < (1 << n); ++st) {
        long long m = 1;
        for (int i = 0; i < n; ++i) {
            m *= a[i][(st >> i) & 1];
        }
        b.push_back(m);
    }
    sort(b.begin(), b.end());
    return b;
}

int solution(int n, const vector<vector<int>>& f, int L, int R) {
    assert(n == f.size() && L <= R && f[0].size() == 2);
    vector<vector<int>> l(f.begin(), f.begin() + n / 2);
    vector<vector<int>> r(f.begin() + n / 2, f.end());

    vector<long long> u = gen(l);
    vector<long long> v = gen(r);

    int ans = 0;
    ++R;
    for (long long x : u) {
        ans += bisect_left(v, (R + x - 1) / x) - bisect_left(v, (L + x - 1) / x);
    }
    return ans;
}

int main() {
    cout << (solution(2, {
  
  {1, 2}, {3, 4}}, 1, 6) == 3) << endl;
    cout << (solution(2, {
  
  {1, 2}, {3, 4}}, 4, 6) == 2) << endl;
    cout << (solution(3, {
  
  {1, 2}, {3, 5}, {2, 4}}, 10, 50) == 7) << endl;
    return 0;
}

 

 

 

 

 

 

运行结果: 

 

 


http://www.kler.cn/a/539470.html

相关文章:

  • 利用 Python 爬虫获取按关键字搜索淘宝商品的完整指南
  • 基于机器学习的DDoS检测系统实战
  • 2月7日QT
  • 寒假2.7
  • opencv图像处理
  • pytest.fixture
  • 蓝桥杯数组分割
  • Redis持久化的两种方式:RDB和AOF
  • RNA研究的新发现,人类未来可能控制基因遗传
  • 什么是 Elasticsearch?
  • 【什么是拆包和粘包?】
  • 消息中间件之kafka
  • Mac上搭建k8s环境——Minikube
  • Axure原型设计:AI开发平台解决方案及设计案例
  • java手动实现常见数据结构
  • 零基础入门AI:如何使用ollama本地部署DeepSeek 开源大模型
  • B+树原理详解及C语言实现
  • 如何使用deepseek开发一个翻译API
  • 韶音科技:消费电子行业售后服务实现数字化转型,重塑客户服务体系
  • 如何使用python制作一个天气预报系统
  • 工业物联网平台-视频识别视频报警新功能正式上线
  • 【kafka实战】06 kafkaTemplate java代码使用示例
  • 语义分割文献阅读——SETR:使用Transformer从序列到序列的角度重新思考语义分割
  • ProcessingP5js游戏掉落的恐龙蛋
  • 如何在Vscode中接入Deepseek
  • 基于房价预测的线性回归算法原理与python实现(附源代码)