P1763 埃及分数 题目传送门
#include<iostream>
using namespace std;
int origin_up,origin_down;
int maxn=-1999;
int minn=10000001;
int minn_layer=10000001;
int memory[10000001];
int read_in[10000001];
int pointer;
//debug layer,minn,memory,down_,pointer,left_down,left_up,minn_layer
int solve(int a_down,int b_down){//最小公约数
if(b_down==0){
return a_down;
}
return solve(b_down,a_down%b_down);
}
//层数,剩余分数分子,剩余分数分母,上一层分母
void dfs(int layer,int left_up,int left_down,int down_){
layer++;
int ls__=solve(left_down,left_up);//最小公约数
left_down/=ls__;
left_up/=ls__;
if(layer>minn_layer){//如果层数大于已知的最小层数就可以返回,无需管有没有搜完
return ;
}
if(left_down>=minn){//无需管剩余分子是否为一,只要大于了已知的最小分子就可以返回
return ;
}
if(left_up==1){//如果剩余的分数的分子为一,即可记录
memory[layer]=left_down;//记录
pointer=layer;
if(minn>left_down&&minn_layer>=layer&&memory[layer]>memory[layer-1]/*不准有相同的 */){
minn=min(minn,left_down);//最小分母
minn_layer=min(layer,minn_layer);//最小层数
for(int i=1;i<=layer;i++){
read_in[i]=memory[i];//答案记录
}
}
return ;
}
bool flag=true;
while(flag){
int ls=(left_down*down_)/solve(left_down,down_);
int ls_left_up=left_up*(ls/left_down);//最大公倍数
int ls_up=(ls/down_);
if(ls_left_up>ls_up){//如果枚举的分数小于剩余分数,进入搜索
memory[layer]=down_;
down_++;//分母枚举
dfs(layer,ls_left_up-ls_up,ls,down_);
if(down_>minn){//剪枝,如果枚举的分母大于已知的最小分母,返回
return ;
}
}else{
down_++;//枚举
if(down_>minn){
return ;
}
}
}
}
int main(){
cin>>origin_up>>origin_down;//分子分母输入
dfs(0,origin_up,origin_down,2);
for(int i=1;i<=pointer;i++){
cout<<read_in[i]<<" ";
}
return 0;
}
怎么优化和剪枝呀?%%%