pku 3601 Tower of Hanoi

 #include <stdio.h> int m[110],F[110], G[110]; int main() { int i, N, M; while(scanf("%d %d", &N, &M) != EOF) { for(i = 1; i <= N; ++i) scanf("%d", &m[i]); F[0] = 0; for (i = 1; i <= N; ++i) F[i] = (F[i-1]*2+m[i])%M; G[1] = 2*(m[1]-1)+1; for(i = 2; i <= N; ++i) { if(m[i] == 1) G[i] = F[i]; else G[i] = 2*F[i-1]+2*m[i]+G[i-1]; G[i] %= M; } printf("%d/n", G[N]%M); } return 0; } /* 假设有n种盘子,其数量分别为m1,m2,……,mn。盘子要从杆A移到杆C,辅助杆为B。 先让我们考虑一个比较简单些的问题: 同种盘子之间无差别。显然,最好的方法是把上面n-1种盘子移到B上,把第n种盘子移到C上,在把上面 n-1种盘子移到C上。这样的结果是第n种盘子逆序,其余盘子同序!(!!!) 设F(n)为此时最优解,显然有F(n)=2*F(n-1)+m(n)。此式可展开为: F(n)=2^(n-1)*m1 + 2^(n-2)*m2 +……+2*m(n-1) + m(n) 现在考虑同种盘子有差别的情况。设G(n)为此时最优解 考虑只有一叠。此时,最好的办法是把上面m-1个盘子放到B上,把最下面一个移到C,再把m-1个移到C。 (注意这过程中盘子间的顺序!)所以我们得到G(1)=2*m-1 当不只一叠时,最好的做法是,先把上面n-1种盘子无差别的移到C,再把第n种直接移到B,再把n-1种 盘子无差别的移到A,再把第n种直接移到C。注意,此时前n-1种和第n种都是顺序的啦!所以再把n-1种 有差别的移到C上即可。 递推式为: G(n)=2*F(n-1)+2*m(n)+G(n-1) */

你可能感兴趣的:(pku 3601 Tower of Hanoi)