HihoCoder 1233 Boxes BFS

来源:互联网 发布:bp神经网络算法步骤 编辑:程序博客网 时间:2024/05/20 05:58

https://hihocoder.com/problemset/problem/1233

题意:有很多个大小不同的盒子,排成一排,可以类似汉诺塔一样的移动他们,每次只能移动每个位置最顶上的那个盒子,只能移动到和他相邻的位置上去,并且是小盒子只能放在大盒子上面,问最后把这些盒子排成一个大小从小到大的顺序,需要的最少的次数,如果不可以,输出-1

想到是状态压缩从终点往回BFS预处理,但想歪了压缩的思路,想法是按位置所有的盒子状态压缩,这样会有很多种不会出现的状态,

看了题解就懂了,按每个盒子所在的位置压缩,n个盒子就一个n进制数,每一位的值代表现在这个盒子在哪个位置上,当然每个位置上最小的值必然就是最顶上的盒子

还有一点也是想歪了。。。。以为不同盒子数量是无差别的,只需要预处理出7个盒子时,对于小数量固定前某部分就可以,其实并不,多了一个盒子数量等于多了一个可移动的位置

#include<bits/stdc++.h>using namespace std;int ans[8][3000005],fac[10],a[10];struct node{    int a,id;}num[10];int cmp(node u,node v){    return u.a<v.a;}int main(){    memset(ans,-1,sizeof(ans));    int n,now=1,state=0,i,j;    //枚举有多少个盒子    for(n=1;n<=7;n++)    {        fac[0]=1;        for(i=1;i<n;i++)        {            fac[i]=fac[i-1]*n;        }        now=1,state=0;        queue<int>Q;        //终点状态值        for(i=0;i<n;i++)        {            state+=now*i;            now*=n;        }        ans[n][state]=0;        Q.push(state);        //BFS预处理所有可达状态的答案        while(!Q.empty())        {            now=Q.front();            Q.pop();            for(i=0;i<n;i++)            {                a[i]=n;            }            state=now;            for(i=0;i<n;i++)            {                int temp=state%n;                if(a[temp]==n)                    a[temp]=i;                state/=n;            }            for(i=0;i<n;i++)            {                if(i!=0)                {                    if(a[i]<n&&a[i]<a[i-1])                    {                        state=now-fac[a[i]];                        if(ans[n][state]==-1)                        {                            ans[n][state]=ans[n][now]+1;                            Q.push(state);                        }                    }                }                if(i!=n-1)                {                    if(a[i]<n&&a[i]<a[i+1])                    {                        state=now+fac[a[i]];                        if(ans[n][state]==-1)                        {                            ans[n][state]=ans[n][now]+1;                            Q.push(state);                        }                    }                }            }        }    }    int T;    cin>>T;    while(T--)    {        state=0;        scanf("%d",&n);        for(i=0;i<n;i++)        {            scanf("%d",&num[i].a);            num[i].id=i;        }        sort(num,num+n,cmp);        now=1;        //压缩成状态值        for(i=0;i<n;i++)        {            state+=now*num[i].id;            now*=n;        }        printf("%d\n",ans[n][state]);    }    return 0;}