题目描述:
把一个真分数分解成若干个分子为1的分数之和
并且要求分数越少越好,最小的分数越大越好
题目分析:
有两个限制条件,考虑到分数的个数实际上就是我们深搜的层数,所以使用迭代加深搜索
题目链接:
Ac 代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define int long long
int ans[10100],sum[10100];
int find(int a,int b)
{
int i=2;
while(1)
{
if(b<a*i) return i;
i++;
}
}
int gcd(int a,int b)
{
return !b?a:gcd(b,a%b);
}
bool check(int deep)
{
int max1=-1,max2=-1;
for(int i=1;i<=deep;i++)
{
if(!ans[i]) return 1;
max1=std::max(max1,sum[i]);
max2=std::max(max2,ans[i]);
}
return max1<max2;
}
bool dfs(int now,int deep,int mx,int x,int y)
{
if(now==deep)
{
if(y%x) return 0;
sum[now]=y/x;
if(check(deep))
for(int i=1;i<=deep;i++) ans[i]=sum[i];
return 1;
}
int w=std::max(find(x,y),mx);
int flag=0;
for(int i=w;;i++)
{
if(y*(deep-now+1)<=i*x) break;
sum[now]=i;
int ax=x*i-y;
int bx=y*i;
int d=gcd(x,y);
if(dfs(now+1,deep,i+1,ax/d,bx/d)) flag=1;
}
return flag;
}
main()
{
int a,b;
scanf("%lld%lld",&a,&b);
int min=find(a,b);
int deep;
for(deep=1;;deep++)
{
memset(ans,0,sizeof(ans));
if(dfs(1,deep,min,a,b)) break;
}
for(int i=1;i<=deep;i++)
printf("%lld ",ans[i]);
return 0;
}