# usaco 5.4 Betsy's Tour(插头DP一条回路)

Betsy's Tour
Don Piele

A square township has been divided up into N2 square plots (1 <= N <= 7). The Farm is located in the upper left plot and the Market is located in the lower left plot. Betsy takes her tour of the township going from Farm to Market by walking through every plot exactly once. Shown below is one possible tour for Betsy when N=3.

----------------
|    |    |    |
| F**********  |
|    |    | *  |
------------*---
|    |    | *  |
|  *****  | *  |
|  * | *  | *  |
---*---*----*---
|  * | *  | *  |
|  M | ******  |
|    |    |    |
----------------

Write a program that will count how many unique tours Betsy can take in going from Farm to Market for any value of N.

### INPUT FORMAT

Line 1: A single integer N (1 <= N <= 7)

### SAMPLE INPUT (file betsy.in)

3


### OUTPUT FORMAT

A single line with a single integer, the number of unique tours.

### SAMPLE OUTPUT (file betsy.out)

2


PS：终于又可以手敲插头DP了，尽量在比赛前熟悉所有的算法和题型

/*
ID: 15114582
PROG: betsy
LANG: C++
*/
#include<cstdio>
#include<cstring>
using namespace std;
const int mm=10007;
struct hashTable
{
int h[mm],s[mm],p[mm],v[mm],t;
{
for(i=h[id];i>=0;i=p[i])
{
v[i]+=val;
return;
}
}
void clear()
{
t=0,memset(h,-1,sizeof(h));
}
}f[2];
int i,j,k,n,g1,g2;
bool g[11][11];
bool ok(int s)
{
if(s==1)return g[i+1][j];
if(s==2)return g[i][j+1];
if(s==3)return g[i+1][j]&&g[i][j+1];
}
{
int n=1,w,x=3<<(j<<1),a=(flag?1:2)<<(j<<1);
while(n)
{
if(flag)a<<=2,x<<=2;
else a>>=2,x>>=2;
w=s&x;
if(w)n+=(w==a)?1:-1;
}
return s^x;
}
void Work(int s,int val)
{
int e,w=j<<1,ss=(s>>w)&15;
if(ss==9)return;
if(!ss)
{
if(ok(3))f[g2].push(s|(9<<w),val);
}
else if(!(ss&3)||!(ss&12))
{
if(ss&3)e=0,ss|=ss<<2;
else e=1,ss|=ss>>2;
if(ok(1+e))f[g2].push(s,val);
if(ok(1+!e))f[g2].push(s^(ss<<w),val);
}
else if(ss==6)f[g2].push(s^(ss<<w),val);
}
int PlugDP()
{
f[0].clear();
f[0].push(1,1);
for(g2=i=0;i<n;++i)
{
for(k=0;k<f[g2].t;++k)f[g2].s[k]<<=2;
for(j=0;j<n;++j)
if(g[i][j])for(g1=g2,g2=!g2,f[g2].clear(),k=0;k<f[g1].t;++k)
Work(f[g1].s[k],f[g1].v[k]);
}
int ret=0;
for(k=0;k<f[g2].t;++k)
if(f[g2].s[k]==1)ret+=f[g2].v[k];
return ret;
}
int main()
{
freopen("betsy.in","r",stdin);
freopen("betsy.out","w",stdout);
while(~scanf("%d",&n))
{
memset(g,0,sizeof(g));
for(i=0;i<n;++i)
for(j=0;j<n;++j)g[i][j]=1;
g[n][0]=1;
printf("%d\n",PlugDP());
}
return 0;
}


©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客