【题解】P1763
题目大意:
- 给出一个分数
,分解为多个分子为 的分数和。
- 要求分数的个数尽量的少,在数量相同的情况下保证最小的分数最大,且每个分数互不相同。
迭代加深搜索:
迭代加深搜索可以看做带深度限制的 DFS
。
首先设置一个搜索深度,然后进行 DFS
,当目前深度达到限制深度后验证当前方案的合理性,更新答案。
不断调整搜索深度,直到找到最优解。
埃及分数具体实现:
- 我们用
lim
限制搜索层数,先从 开始,每次深度加一。 - 搜索时每一层比上一层的分数小,即分母一次比一次大,每次枚举出
后,用当前分数减去,然后递归求解剩余的分数。
每层搜索枚举的限制条件:
-
保证当前深度分母大于上一深度分母。
-
枚举的
小于当前分数,不可能存在等于的状态,因为此种最优解会在限制深度较小的时候出现。 -
假设当前剩余分数为
,剩余深度为 ,则 。
Code:
#include <cstdio>
#include <iostream>
using namespace std;
#define ll long long
ll num[10005], tot[10005];
ll lim, ans;
bool flag;
inline void dfs(ll dep, ll mol, ll den, ll pre) {
if (dep == lim + 1) {
if (mol == 0) {
flag = 1;
if (num[lim] < tot[lim]) {
for (ll i = 1; i <= lim; i++)
tot[i] = num[i];
ans = num[lim];
}
}
return ;
}
if (den * (lim + 1 - dep) / mol > ans || num[lim] > ans)
return ;
for (int i = max(pre, den / mol); i <= den * (lim + 1 - dep) / mol; i++) {
num[dep] = i;
dfs(dep + 1, mol * i - den, den * i, i + 1);
}
}
ll a, b;
int main() {
scanf("%lld %lld", &a, &b);
for (lim = 1; ; lim++) {
tot[lim] = 0x3f3f3f3f;
ans = 0x3f3f3f3f;
dfs(1, a, b, 1);
if (flag)
break;
}
for (register ll i = 1; i <= lim; i++)
printf("%lld ", tot[i]);
return 0;
}
本文来自博客园,作者:zhou_ziyi,转载请注明原文链接:https://www.cnblogs.com/zhouziyi/p/16526541.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具