[题解]「一本通 1.3 练习 1」埃及分数
Posted sky-zxz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[题解]「一本通 1.3 练习 1」埃及分数相关的知识,希望对你有一定的参考价值。
这道题比较经典。
算法:迭代加深+IDA*
优化:
1.迭代加深
2.确定从小到大的搜索顺序
3.确定搜索上下界
(1)以i为分母的数字不能大于a/b.
(2)如果后面的数字都以i为分母仍然<=a/b,退出。
细节:
(1)在通分过程中会爆int。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define ll unsigned long long #define R register using namespace std; const int N=1e5+5; ll ans_a,ans_b,ans[N],lin[N],k,flag,vis[N]; inline ll gcd(R ll a,R ll b){ if(b==0)return a; return gcd(b,a%b); } inline void dfs(R ll x,R ll a,R ll b,ll lst)//正在填第几个 { if(x==k){ if(b%a==0) { flag=1; ans[k]=b/a; if(ans[k]<lin[k]) for(R ll i=1;i<=k;i++) lin[i]=ans[i]; } return; } for(R ll i=lst+1;i;i++) { if((k-x+1)*b<=a*i)break; if(i*a<b)continue; R ll zi=i*a-b; R ll mu=i*b; R ll g=gcd(zi,mu); ans[x]=i; dfs(x+1,zi/g,mu/g,i); ans[x]=0; } } int main(){ scanf("%lld%lld",&ans_a,&ans_b);cn k=0; k=gcd(ans_a,ans_b); ans_a/=k; ans_b/=k; k=0; memset(lin,127,sizeof(lin)); while(!flag) { k++; dfs(1,ans_a,ans_b,0); } for(R ll i=1;i<=k;i++) printf("%lld ",lin[i]); return 0; } //迭代加深 //上下界剪枝
以上是关于[题解]「一本通 1.3 练习 1」埃及分数的主要内容,如果未能解决你的问题,请参考以下文章