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

《P1763 埃及分数》

题目描述

来源:BIO 1997 Round 1 Question 3

在古埃及,人们使用单位分数的和(形如 a1​ 的,a 是自然数)表示一切有理数。如:32​=21​+61​,但不允许 32​=31​+31​,因为加数中有相同的。对于一个分数 ba​,表示方法有很多种,但是哪种最好呢?首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越好。如:

4519​4519​4519​4519​4519​​=31​+121​+1801​=31​+151​+451​=31​+181​+301​=41​+61​+1801​=51​+61​+181​​

最好的是最后一种,因为 181​ 比 1801​,451​,301​ 都大。
注意,可能有多个最优解。如:

21159​21159​​=41​+361​+6331​+37981​=61​+91​+6331​+37981​​

由于方法一与方法二中,最小的分数相同,因此二者均是最优解。

给出 a,b,编程计算最好的表达方式。保证最优解满足:最小的分数 ≥1071​。

输入格式

一行两个整数,分别为 a 和 b 的值。

输出格式

输出若干个数,自小到大排列,依次是单位分数的分母。

输入输出样例

输入 #1复制

19 45

输出 #1复制

5 6 18

说明/提示

1<a<b<1000

代码实现:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

typedef long long LL;
vector<LL> ans_d, temp_d;
int max_depth;

// 求最大公约数
LL gcd(LL a, LL b) {
    return b == 0 ? a : gcd(b, a % b);
}

// 约分分数 a/b
pair<LL, LL> reduce(LL a, LL b) {
    LL g = gcd(a, b);
    return {a / g, b / g};
}

// 比较两个解的优劣
bool better(const vector<LL>& a, const vector<LL>& b) {
    if (a.empty()) return false;
    if (b.empty()) return true;
    for (int i = a.size() - 1; i >= 0; i--) {
        if (a[i] != b[i]) return a[i] < b[i];
    }
    return false;
}

// 深度优先搜索寻找最优解
bool dfs(int depth, LL a, LL b, LL from) {
    if (depth == max_depth) {
        if (a != 1) return false;
        if (b < from) return false;
        temp_d.push_back(b);
        if (better(temp_d, ans_d)) {
            ans_d = temp_d;
        }
        temp_d.pop_back();
        return true;
    }

    bool found = false;
    from = max(from, (b + a - 1) / a); // 计算k的下界
    for (LL k = from; ; k++) {
        // 剪枝:如果剩余的深度无法达到更好的解
        LL max_remaining = b * (max_depth - depth + 1);
        if (k > max_remaining) break;

        LL new_a = a * k - b;
        LL new_b = b * k;
        if (new_a <= 0) continue;

        pair<LL, LL> reduced = reduce(new_a, new_b);
        LL na = reduced.first;
        LL nb = reduced.second;
        
        temp_d.push_back(k);
        if (dfs(depth + 1, na, nb, k + 1)) {
            found = true;
        }
        temp_d.pop_back();
    }
    return found;
}

int main() {
    LL a, b;
    cin >> a >> b;

    pair<LL, LL> reduced = reduce(a, b);
    a = reduced.first;
    b = reduced.second;

    for (max_depth = 1; ; max_depth++) {
        temp_d.clear();
        if (dfs(1, a, b, (b + a - 1) / a)) {
            break;
        }
    }

    sort(ans_d.begin(), ans_d.end());
    for (vector<LL>::iterator it = ans_d.begin(); it != ans_d.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}    

http://www.xdnf.cn/news/9513.html

相关文章:

  • Acrobat Reader 无法在 Windows 11及10 中打开的5种修复方法
  • 数据库表添加索引
  • STM32 Modbus RTU从机开发实战:核心实现与五大调试陷阱解析
  • 什么是Windows内存压缩? win10/11系统启用和禁用内存压缩的教程
  • HTB-Puppy
  • DAY 38 Dataset和Dataloader类
  • Linux网络编程(一)
  • 医疗影像检测系统设计与实现
  • open3d保存为pcl可以读取的ply点云
  • Windows 子系统 WSL 中宝塔安装 supervisor 启动失败解决方案
  • 《计算机组成原理》第 1 章 - 计算机系统概论
  • 工控安全审计与网络流量监控系统的协同防御
  • ‌CDGP|企业数据治理:莫让“打补丁”成为常态
  • STL容器使用中的常见问题解析
  • 辛格迪客户案例 | 博福-益普生实施YonSuite,同步开展计算机化系统验证(CSV)
  • Druid连接池使用和源码分析
  • 为Windows用户量身定制的监控方案
  • 通过 API 获取 1688 平台订单接口的技术实现
  • LeetCode 118 题解--杨辉三角
  • 软考 系统架构设计师系列知识点之杂项集萃(77)
  • 1435系列信号发生器
  • 2025年上半年软考系统架构设计师--案例分析试题与答案
  • python 生成复杂表格,自动分页等功能
  • 自动驾驶规划控制教程——不确定环境下的决策规划
  • 火柴INIBOX矿机实测850M算力即将改写Initverse挖矿规则
  • 模型可信度
  • 缩量资金迁徙下的短期博弈
  • phpstudy(1) -- 记录
  • Orpheus-TTS:AI文本转语音,免费好用的TTS系统
  • 第二十二章:数据治理之数据价值:数据价值知多少