埃及分数

  1. 题意:需要表示的分数a/b(0<a<b<1000),求出最好的表达方式中各个单位分数的分母。最好表达式:加数最少且分母越小。
  2. 分析:想到使用dfs,但时间开销大,使用IDDFS。然后考虑处理分数的问题。
  • 分数处理
    1. 将分子用a表示,将分母用b表示。a/b-1/i=ai/bi+b/bi=(ai-b)/bi.当a==1时,最后一个分母为b,再进行判断。
    2. 优化分母下限:设当前深度到极限深度值为k,当前分母为i,k(1/i)>a/b即k(y/x)>i
    3. 优化分母上限:(1).当前分母大于上一个分母;(2).1/i<a/b即i<b/a; 二者最大值为上限。

code

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N=1005;
int na,nb,m,dp,res[N],ans[N];
bool flag;

 int gcd(int a,int b)
{
    if (b==0) return a;
	return gcd(b,a%b);
} 
 
 void iddfs(int t,int a,int b)
{
	if (t-1==dp) return;
	if (a==1)
	{
		if (b>res[t-1])
		{
			res[t]=b;
			if (!flag||ans[t]>res[t]) memcpy(ans,res,sizeof(res));
			flag=true;
		}
		return;
	}
	int resa,resb,m;
	for (int i=(dp-t+1)*b/a; i>=max(res[t-1]+1,b/a+1); i--)
	{
		res[t]=i;
		resa=a*i-b; resb=b*i;
		m=gcd(resa,resb);
		resa/=m; resb/=m;
		iddfs(t+1,resa,resb);
		res[t]=0;
	}
}
 int main()
{
	scanf("%d%d",&na,&nb);
	m=gcd(na,nb);
	na/=m; nb/=m;
	while (!flag)
	{
		dp++;
		memset(res,0,sizeof(res));
		memset(ans,0,sizeof(ans));
		iddfs(1,na,nb);
	}
	for (int i=1; i<=dp; i++) printf("%d ",ans[i]); printf("\n");
	return 0;
}

注:在rqnoj上提交,oj数据有问题

posted @ 2020-01-13 15:54  Allen_Gun  阅读(187)  评论(0编辑  收藏  举报