BZOJ 1087 [SCOI2005]互不侵犯King
暴力状压dp。。。
好久不写状压dp,先水一个~
View Code
1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cstdio> 5 #include <algorithm> 6 7 #define N 1000 8 9 using namespace std; 10 11 int num,n,m; 12 int zt[N],gs[N]; 13 long long dp[11][1<<11][90]; 14 bool map[N][N]; 15 16 inline bool check(int x,int y) 17 { 18 if(x&(y<<1)) return false; 19 if(x&(y>>1)) return false; 20 if(x&y) return false; 21 return true; 22 } 23 24 inline bool judge(int x) 25 { 26 if(x&(x<<1)) return false; 27 if(x&(x>>1)) return false; 28 return true; 29 } 30 31 inline int getnum(int x) 32 { 33 int res=0; 34 while(x) 35 { 36 if(x&1) res++; 37 x>>=1; 38 } 39 return res; 40 } 41 42 inline void prev() 43 { 44 int sum=(1<<n)-1; 45 for(int i=0;i<=sum;i++) 46 if(judge(i)) 47 { 48 zt[++num]=i; 49 gs[num]=getnum(i); 50 } 51 for(int i=1;i<=num;i++) 52 for(int j=i;j<=num;j++) 53 if(check(zt[i],zt[j])) 54 map[j][i]=map[i][j]=true; 55 } 56 57 inline void go() 58 { 59 dp[0][1][0]=1LL; 60 for(int i=0;i<n;i++) 61 for(int j=1;j<=num;j++) 62 for(int k=0;k<=m;k++) 63 if(dp[i][j][k]) 64 for(int p=1;p<=num;p++) 65 if(map[j][p]&&k+gs[p]<=m) 66 dp[i+1][p][k+gs[p]]+=dp[i][j][k]; 67 long long sum=0; 68 for(int i=1;i<=num;i++) 69 sum+=dp[n][i][m]; 70 printf("%lld\n",sum); 71 } 72 73 int main() 74 { 75 scanf("%d%d",&n,&m); 76 prev(); 77 go(); 78 return 0; 79 }
没有人能阻止我前进的步伐,除了我自己!