前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【算法竞赛 - 搜索】埃及分数

【算法竞赛 - 搜索】埃及分数

作者头像
Livinfly
发布2022-10-26 16:13:09
2610
发布2022-10-26 16:13:09
举报
文章被收录于专栏:Livinfly

题目跳转

Luogu P1763

题目大意

把一个分数,分解为若干个分子为一分母不同的的和。 最终输出,以分解的个数最小为前提,最小的一个分数的分母最小,即该分数最大。

思路

IDDFS - 剪枝

暴力写的话,IDDFS比较模板,难点在于剪枝。(我认为这个剪枝事实上让这道题有点IDA*的意味了)

题目中说明答案中的分母最大为1e7,然而直接循环是不能接受的。

因此,我们要缩小遍历范围

下界 —— max(取的上一个数+1,当前相减后剩余的分数的存在的最大的1/x) 上界 —— min(1e7, 剩余的层数都取同一个分母(使得总和与当前的剩余相等)

CODE

代码语言:javascript
复制
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>

using namespace std;

typedef long long LL;

const int N = 100010;

struct Node
{
  int up, down;
} a;

int path[N], ans_path[N];
bool flag;

LL gcd(LL a, LL b)
{
  return b ? gcd(b, a % b) : a;
}
Node Node_sub(Node a, Node b) // a-b
{
  LL tx, ty, d;
  ty = (LL)a.down * b.down;
  tx = (LL)a.up * b.down - (LL)b.up * a.down;
  if (!tx)
    return (Node){0, 1};
  d = gcd(tx, ty);
  if (d)
    tx /= d, ty /= d;
  if (!d || ty > (int)1e7 || tx < 0)
    tx = -1;
  if (tx == 0)
    ty = 1;
  return (Node){(int)tx, (int)ty};
}
void dfs(int u, int id, Node remain, int depth)
{
  if (u == depth && remain.up == 0)
  {
    if (!flag || path[u - 1] < ans_path[u - 1])
    {
      memcpy(ans_path, path, sizeof path);
      flag = true;
    }
    return;
  }
  int l = max(id, remain.down / remain.up), r = min(remain.down * (depth - u) / remain.up, (int)1e7); // 强力剪枝 - 缩小范围
  for (int i = l; i <= r; i++)
  {
    Node t = Node_sub(remain, (Node){1, i});
    if (t.up == -1)
      continue;
    path[u] = i;
    dfs(u + 1, i + 1, t, depth);
    path[u] = 0;
  }
}

int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  //   freopen("i.txt", "r", stdin);
  // freopen("o.txt", "w", stdout);
  cin >> a.up >> a.down;
  int depth = 1;
  while (true)
  {
    dfs(0, 2, a, depth);
    if (flag)
      break;
    depth++;
  }
  for (int i = 0; i < depth; i++)
    cout << ans_path[i] << ' ';
  cout << '\n';
  return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年08月12日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目跳转
  • 题目大意
  • 思路
  • CODE
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档