新汉诺塔(初步接触退火)
Posted d-o-time
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了新汉诺塔(初步接触退火)相关的知识,希望对你有一定的参考价值。
P1242 新汉诺塔
此题的最后一个数据点不适用于贪心算法,所以每次将大的优先移到目标位置有很小的概率不是最优解,但是毕竟是最优解的概率还是很大的。所以用模(yi)拟(tong)退(luan)火(gao)就可以了,反正也是随机碰碰运气的。概率嘛~~~~,只要你的srand能过,那就能过啦。
//退火算法,洛谷hack掉了贪心,无语了。 #include<cstdio> #include<cstdlib> #include<iostream> using namespace std; #define MAXN 100 #define MAXM 1000000 #define INF 2000000000 int n,m,x,ans=INF,tans,cnt; int A[MAXN],B[MAXN],tA[MAXN],tB[MAXN]; int tI[MAXM],tX[MAXM],tY[MAXM],I[MAXM],X[MAXM],Y[MAXM]; char p[5]=‘\0‘,‘A‘,‘B‘,‘C‘; void dfs(int id,int b) if(tA[id]==b)return ; for(int i=id-1;i>=1;i--) dfs(i,6-tA[id]-b); cnt++; tI[cnt]=id; tX[cnt]=tA[id]; tY[cnt]=b; //printf("move %d from %c to %c\n",id,p[tA[id]],p[b]); tans++; tA[id]=b; void update() ans=tans; for(int i=1;i<=cnt;i++) I[i]=tI[i]; X[i]=tX[i]; Y[i]=tY[i]; void print() for(int i=1;i<=ans;i++) printf("move %d from %c to %c\n",I[i],p[X[i]],p[Y[i]]); printf("%d\n",ans); int main() scanf("%d",&n); for(int i=1;i<=3;i++) scanf("%d",&m); for(int j=1;j<=m;j++) scanf("%d",&x); A[x]=i; for(int i=1;i<=3;i++) scanf("%d",&m); for(int j=1;j<=m;j++) scanf("%d",&x); B[x]=i; srand(19260817); for(int G=1;G<=100;G++) tans=0; cnt=0; for(int i=1;i<=n;i++) tA[i]=A[i], tB[i]=B[i]; for(int i=n;i>=1;i--) if(rand()%(n-i+2)==0) dfs(i,6-A[i]-B[i]);//这里必须写(n-i+2),这是退火的精髓?其实我可能要再去看一看。呵呵。 else dfs(i,B[i]); for(int i=n;i>=1;i--) dfs(i,B[i]); if(tans<ans) update(); print(); return 0;
以上是关于新汉诺塔(初步接触退火)的主要内容,如果未能解决你的问题,请参考以下文章