poj 1945 Power Hungry Cows 启发式搜索

来源:互联网 发布:2017中超守门员数据 编辑:程序博客网 时间:2024/06/05 20:31
这个题目用了启发式搜索来做,hash判重,优先队列储存节点。启发式函数就是大的数字x*2^k>n,即为k。
x为节点中较大值,y为节点中较小值
然后后面就是一些剪枝了,当x>2*n不能得出最优解。当y==0,不能得出最优解。当x==y,不能得出最优解。
还有一个比较关键的剪枝,gcd(x,y)不能整除n时,得不出结果。

#include
#include
#include
#include
#include
using namespace std;
const int maxn=160000+10;
int n;
int d[22222];

int time;

struct node
{
    int x,y,h,cost;
    bool operator <(const node &xx) const
    {
       return(cost>xx.cost);
    }
};

priority_queue que;

int hash[maxn],lon;
struct
{
    int x,y,cost,next;
}data[11111111];

void insert(struct node *p)
{
    inttmp=p->x+p->y;
   data[++lon].x=p->x;
   data[lon].y=p->y;
   data[lon].cost=p->h;
   data[lon].next=hash[tmp];
    hash[tmp]=lon;
}

int gcd(int a,int b)
{
    int tmp;
    while(a%b)
    {
       tmp=a%b;
       a=b;
       b=tmp;
    }
    return(b);
}

int check(int x,int y,int h)
{
    if(x<=0)return(0);
    if(y!=0)
    if(n%gcd(x,y)!=0)
    {
       return(0);
    }
    if(x==n||y==n)
    {
       printf("%d\n",h);
       exit(0);
    }
    if(x
    swap(x,y);

   if(x>n&&y>n) return(0);
    if(x>n*2)return(0);
    if(x>n&&y==0)return(0);
    if(x==y)return(0);

    for(intk=hash[x+y];k!=-1;k=data[k].next)
    {
       if(data[k].x==x&&data[k].y==y)
       {
          if(data[k].cost>h)
           {
              data[k].cost=h;
              return(1);
           }
           else
          return(0);
       }
    }

    return(1);
}

int cal(int x,int y)
{
    if(x==n)
    return (0);

    if(x
    return(d[x]);
    if(x>n)
    {
       int k=1;
       int tmp=x-n;
       while(y
       {
           k++;
          y<<=1;
       }
       return(k);
    }
}

void work(int x,int y,int h)
{
    if(x
    swap(x,y);
    struct node p;
    p.x=x;
    p.y=y;
    p.h=h;
    p.cost=h+cal(x,y);

    insert(&p);
    que.push(p);

}

int bfs()
{
   while(!que.empty())
    que.pop();

   memset(hash,-1,sizeof(hash));
    lon=0;
    struct node p;
    p.x=1;
    p.y=0;
    p.h=0;
   p.cost=p.h+cal(1,0);
    insert(&p);
    que.push(p);
   while(!que.empty())
    {
       intx=que.top().x,y=que.top().y,h=que.top().h+1,cost=que.top().cost;
       que.pop();

       if(x==n||y==n)
       return(cost);

       if(check(x+y,y,h))
       work(x+y,y,h);

       if(check(x,x+y,h))
       work(x,x+y,h);

       if(check(x+x,y,h))
       work(x+x,y,h);

       if(check(x,x+x,h))
       work(x,x+x,h);

       if(check(y+y,y,h))
       work(y+y,y,h);

       if(check(y+y,x,h))
       work(y+y,x,h);

       if(check(x-y,y,h))
       work(x-y,y,h);

       if(check(x,x-y,h))
       work(x,x-y,h);
    }
}

int main()
{
   scanf("%d",&n);
    for(inti=n,j,t=0;i>=1;i=j)
    {
       j=i/2,t++;
       for(int k=i-1;k>j;k--)
       d[k]=t+1;
       d[j]=t;
    }
    bfs();
    return 0;
}