poj3134 Power Calculus

题目描述:

你现在有x^1,每动一步可以用当前存在的x^a和x^b获得x^(a+b)或x^(abs(a-b))。给出n(n<=1000),求最少多少步能得到x^n。

题解:

IDDFS。枚举步数,然后dfs+剪枝。

剪枝:

1.目标高于上限时减掉;

2.当前存在两个>n或以上时减掉。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 1050
int n,lim;
int a[N]={1};
int vis[N]={0,1};
bool fg=0;
void dfs(int dep,int mx)
{
    if(a[dep-1]==n)fg=1;
    if(fg)return ;
    if(dep>lim)return ;
    if(mx*(1<<(lim-dep+1))<n)return ;
    for(int i=0;i<dep;i++)
    {
        int x = a[i]+a[dep-1];
        if(mx<n||x<n)
        {
            if(!vis[x])
            {
                vis[x]=1;
                a[dep]=x;
                dfs(dep+1,max(mx,x));
                vis[x]=0;
            }
        }
        x=a[i]-a[dep-1];
        if(x<0)x=-x;
        if(mx>n&&x>n)continue;
        if(!vis[x]&&x)
        {
            vis[x]=1;
            a[dep]=x;
            dfs(dep+1,max(mx,x));
            vis[x]=0;
        }
    }
}
int main()
{
    while(scanf("%d",&n)>0)
    {
        fg=0;
        if(!n)break;
        if(n==1)
        {
            printf("0\n");
            continue;
        }
        for(lim=1;;lim++)
        {
            dfs(1,1);
            if(fg)
            {
                printf("%d\n",lim);
                break;
            }
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/LiGuanlin1124/p/10010215.html