标签:
传送门
搜索套餐第二题 迭代加深
比较经典 由于他在时间和空间上的搜索层数都是未知
所以我们呢可以给他一个预定的层数进行搜索
如果本层不存在最优解
那就跳到下一层再进行搜索
对于每一层的搜索注意剪枝
首先是可行性剪枝 对于本数 如果本数大于所要的 那么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;}
}
}
标签:
原文地址:http://blog.csdn.net/qq_32451161/article/details/51363658