USACO 5.4.4 Betsy's Tour

题目大意

求n*n的网格中,以左上角为起点,以右下角为终点的哈密顿路径的条数。
哈密顿路径:经过且只经过所有点一次的路径。
 
简单题解
看到哈密顿路径,我们就自然地想到了基于连通性状态压缩的递推
参见2008年陈丹琦的论文《基于连通性状态压缩的动态规划问题》。(吐槽:是递推啊。。)
由于路径起点和终点固定,为使问题简单化,我们可以将起点与终点连结起来,转化为哈密顿回路。
为方便转移,将网格顺时针旋转90°。
 
我的代码
 1 /*
 2 ID:t-x.h1
 3 LANG:C++
 4 TASK:betsy
 5 */
 6 #include<cstdio>
 7 #include<cstring>
 8 FILE *fi=fopen("betsy.in","r"),*fo=fopen("betsy.out","w");
 9 const int MAXf=999,N=9;
10 int a[MAXf],tot;
11 int brm[MAXf][N],br[N];
12 int f[N][1<<16];
13 int main()
14 {
15         int n,m,ans=0,i,j,k,t,p,q;
16         fscanf(fi,"%d",&n);
17         if(n==1)
18         {
19                 ans=1;
20                 goto to;
21         }
22         m=1<<(n+1)*2;
23         for(i=0;i<m;++i)
24         {
25                 for(t=i,j=0,k=0;j<=n;++j,t>>=2)
26                         if((t&3)==1)
27                                 br[k++]=j;
28                         else if((t&3)==2)
29                                 if(k--)
30                                         brm[tot][br[k]]=j,brm[tot][j]=br[k];
31                                 else
32                                         break;
33                         else if((t&3)==3)
34                         {
35                                 k=-1;
36                                 break;
37                         }
38                 if(!k)
39                         a[tot++]=i;
40         }
41         f[n][(1<<(2*n-1))|1]=1;
42         for(k=1;k<=n;++k)
43         {
44                 for(i=0;i<tot;++i)
45                         f[0][a[i]]=a[i]&3?0:f[n][a[i]>>2];
46                 for(i=1,t=0;i<=n;++i,t+=2)
47                 {
48                         memset(f[i],0,sizeof(f[i]));
49                         for(j=0;j<tot;++j)
50                         {
51                                 p=(a[j]>>t)&3,q=(a[j]>>(t+2))&3;
52                                 if(!p && !q)
53                                         f[i][a[j]|(9<<t)]+=f[i-1][a[j]];
54                                 else if(p && q)
55                                         if(p==q)
56                                                 if(p==1)
57                                                         f[i][a[j]^(5<<t)^(3<<brm[j][i]*2)]+=f[i-1][a[j]];
58                                                 else
59                                                         f[i][a[j]^(10<<t)^(3<<brm[j][i-1]*2)]+=f[i-1][a[j]];
60                                         else
61                                                 if(p==1)
62                                                 {
63                                                         if(k==n && i==n && a[j]==9<<t)
64                                                                 ans+=f[i-1][a[j]];
65                                                 }
66                                                 else
67                                                         f[i][a[j]^(6<<t)]+=f[i-1][a[j]];
68                                 else
69                                 {
70                                         f[i][a[j]]+=f[i-1][a[j]];
71                                         f[i][a[j]^(p<<t)^(q<<(t+2))^(p<<(t+2))^(q<<t)]+=f[i-1][a[j]];
72                                 }
73                         }
74                 }
75         }
76 to:     fprintf(fo,"%d\n",ans);                        
77         fclose(fi);
78         fclose(fo);
79         return 0;
80 }

 

posted @ 2012-08-18 12:56  凌云七风  阅读(430)  评论(0编辑  收藏  举报