分数拆分
这一题运用了迭代加深的深度优先搜索
因为分数拆分如果不进行限制的话会出现无穷多的深度,又因为题目要求用最少的分数因此可以从小到大加深搜索
在每次搜索时会限定一个深度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循环的)
这一题运用了迭代加深的深度优先搜索
因为分数拆分如果不进行限制的话会出现无穷多的深度,又因为题目要求用最少的分数因此可以从小到大加深搜索
在每次搜索时会限定一个深度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;
}