码迷,mamicode.com
首页 > 其他好文 > 详细

埃及分数 IDS 搜索 Vijos 1308

时间:2016-05-12 15:26:45      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:

传送门
搜索套餐第二题 迭代加深
比较经典 由于他在时间和空间上的搜索层数都是未知
所以我们呢可以给他一个预定的层数进行搜索
如果本层不存在最优解
那就跳到下一层再进行搜索

对于每一层的搜索注意剪枝
首先是可行性剪枝 对于本数 如果本数大于所要的 那么T掉本点
如果本数乘三尚且小于所求 T掉本点
注意分数的性质 注意通分
注意字典序最小的要求
吐槽一下 本题数据略弱
下面是AC代码 略慢  可优化

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
long long  s[500],ans[500],sr,ar;
struct score
{
    long long up,down;
    score () {}
    score (long long x,long long y)
    : up(x),down(y) {x=x/__gcd(x,y);y=y/__gcd(x,y);}
    double calc()
    {return 1.0*up/down;}
};
score operator-(score A,score B)
{
    long long tmp1=A.up,tmp2=A.down,tmp3=B.up,tmp4=B.down;
    tmp1*=tmp4,tmp3*=tmp2;tmp1-=tmp3;
    tmp2*=tmp4;
    long long k=__gcd(tmp1,tmp2);
    tmp1/=k,tmp2/=k;
    score C(tmp1,tmp2);
    return C;
}
bool operator<(score A,score B)
{return A.calc() < B.calc();}
score operator*(int x,score B)
{score C(B.up*x,B.down);return C;}
int tot;
bool cmp=false;
void check()
{
    long long tmp1=sr,tmp2=ar;
    if(!ar)
    {for(int i=1;i<=sr;++i)ans[i]=s[i];ar=sr;return;}
    if(s[tmp1]>ans[tmp2])return;
    if(s[tmp1]<ans[tmp1])
        {for(int i=1;i<=sr;++i)
    ans[i]=s[i];return ;}
    tmp1=1;
    while(ans[tmp1]==s[tmp1])tmp1++;
    if(ans[tmp1]>s[tmp1])
    for(int i=tmp1;i<=sr;++i)
    ans[i]=s[i];
}
void put()
{
    for(int i=1;i<ar;++i)
        printf("%lld ",ans[i]);
    printf("%lld",ans[ar]);
}
void DFS(score A,int depth,int x,int will)
{
    if(depth >= will)
    {if(A.up==1){s[++sr]=x;s[++sr]=A.down;if(s[sr]==s[sr-1]){sr-=2;return ;}check();sr-=2;cmp=true;}return;}
    if(1.0*(will-depth+1)/x<A.calc())return;
    double tmp=1.0*(will-depth+1)/A.calc();
    for(int i=x+1;tmp>i;++i)
    {
        score  C(1,i);
        if(A<C)continue;
        score tmp (1,i);
        score B=A-tmp;
        if(depth>1)s[++sr]=x;
        DFS(B,depth+1,i,will);
        if(depth>1)--sr;
    }
}
int main()
{
    int a,b;
    cin>>a>>b;
    score A(a,b);
    int cnt  = 0 ;
    while(1)
    {
        cnt++ ;
        DFS(A,1,1,cnt);
        if(cmp) {put();return 0;}
    }   
}

技术分享

埃及分数 IDS 搜索 Vijos 1308

标签:

原文地址:http://blog.csdn.net/qq_32451161/article/details/51363658

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!