JZOJ 1213. 棋盘上的士兵
题目
分析
-
正解还真的是状压但是我不知道数组怎么开于是只有60?
代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 using namespace std; 6 int n,m; 7 long long map[32][32]; 8 long long f[2][1<<20]; 9 long long a[32]; 10 void dfs(int x,int y) 11 { 12 if (x>(n+n)/2) return; 13 map[x][y]=0; 14 dfs(x+1,y-1),dfs(x+1,y+1); 15 } 16 int main () 17 { 18 freopen("chess.in","r",stdin); 19 freopen("chess.out","w",stdout); 20 cin>>n>>m; 21 for (int i=1;i<=n+n-1;i++) for (int j=1;j<=n+n-1;j++) map[i][j]=1; 22 dfs(1,(n+n)/2); 23 for (int i=(n+n)/2+1,k=2;i<=n+n-1;i++,k+=2) for (int j=1;j<=n+n-1;j++) map[i][j]=map[i-k][j]; 24 for (int i=1;i<=n+n-1;i++) for (int j=1;j<=n+n-1;j++) a[i]=(a[i]<<1)+map[i][j]; 25 int maxn=(1<<(n+n-1))-1; 26 f[0][(1<<(n+n)/2-1)]=1; 27 f[0][0]=1; 28 int nn=n+n-1,x=0; 29 for (int i=2;i<=nn;i++) 30 { 31 x^=1; 32 for (int j=0;j<=maxn;j++) 33 { 34 f[x][j]+=f[x^1][j]; 35 for (int k=1;k<=nn;k++) 36 { 37 if (!(j&(1<<k-1))&&!(a[i]&(1<<k-1))) 38 f[x][j|(1<<k-1)]+=f[x^1][j]; 39 } 40 } 41 memset(f[x^1],0,sizeof(f[x^1])); 42 } 43 long long ans=0; 44 for (int j=0;j<=maxn;j++) 45 if (__builtin_popcount(j)==m) ans+=f[x][j]; 46 cout<<ans; 47 }
为何要逼自己长大,去闯不该闯的荒唐