uestc oj 1668 分数拆分

分数拆分
  这一题运用了迭代加深的深度优先搜索
  因为分数拆分如果不进行限制的话会出现无穷多的深度,又因为题目要求用最少的分数因此可以从小到大加深搜索
  在每次搜索时会限定一个深度deep,深度达到deep之后判断分数是否拆分完毕
  要建立两个数组,一个是临时数组temp用于存储单次DFS得到的解,ans存储最优解,每次发现此深度值下的解之后与
 最优解进行比较看是否得到了更忧的解
    if(y%x==0) down = y/x;
    else down = y/x+1;


    up = y*(deep-now_deep)/x;
    if(up>ans[now_deep+1])  
    up=ans[now_deep+1];
  在深度搜索的时候要给每一位要搜索的分母设置上下限 同时可以做些小剪枝(比如这一位的分母值不能大于作为最优解的那一位)
  还有要注意的就是在深度搜的时候,由于数据的关系分母可能到达64位数据所以用long long
  一旦某一深度的搜索得出最优解 直接跳出循环(其实是个死的for循环的)
  






#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
long long temp[100], ans[100], M; bool flag;
long long common(long long a,long long b)
{
    if(a==0) return b;
    else
    return common(b%a,a);
}




void dfs(long long x, long long y, int now_deep, int deep)
{
   if (now_deep == deep)
   {
      if (x) return;
      int real = 0;
      for (int i = deep; i > 0; i--)
        {
            if (temp[i] < ans[i])
                {
                    real = 1;
                    break;
                }
            if (temp[i] > ans[i])
                {
                    real = 0;
                    break;
                }
        }


       if (real == 1)
       {
            memcpy(ans, temp, sizeof(ans));
            ans[0] = ans[deep];
        }


       flag = true; return;
   }


    int down ,up;


    if(y%x==0) down = y/x;
    else down = y/x+1;
    if(down<temp[now_deep]+1) down = temp[now_deep]+1;


    up = y*(deep-now_deep)/x;
    if(up>ans[now_deep+1])  
    up=ans[now_deep+1];


    for (long long a = down; a <= up; a++)
   {
       long long xx = a * x - y, yy = a * y;
       temp[now_deep + 1] = a;
       long long div = common(x,y);
        dfs(xx / div, yy / div, now_deep + 1, deep);
    }
}


int main(void)
{
//freopen("1.txt", "r", stdin);


  int T; scanf("%d", &T);
 while (T--)
   {
      int a, b; scanf("%d%d", &a, &b);
        flag = false;
        for (int deep = 1; ; deep++)
        {
            memset(temp, 0, sizeof(temp));
            for (int i = 0; i <= deep; i++) ans[i] = 0x7fffffffLL;
           dfs(a, b, 0, deep);
            if (flag == true)
            {
                for (int i = 1; i <= deep; i++) printf("%lld ", ans[i]);
                break;
             }
         }
       printf("\n");
    }
    return 0;
 }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值