HDU 4462 Scaring the Birds
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=4462
典型的的状态压缩问题,所谓状态压缩是指当前状态用二进制的形式来存储,当然也可以用其它进制。在实际效果中可以将时间复杂度O(n!)
变成O(n*2^n)的时间复杂度,提高了运行速度。
本题就是采用这个道理,将状态以二进制存储而不去管到底是放置哪个稻草,放了就是1,没放就是0,并求出最小放置的稻草个数。
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #include<stdlib.h> 5 const int maxn=50+2; 6 int vis[maxn][maxn],x[12],y[12],r[12],n,k; 7 bool solve(void) 8 { 9 for(int i=1;i<=n;i++) 10 for(int j=1;j<=n;j++){ 11 bool flag=false; 12 for(int s=0;s<k;s++) 13 if(i==x[s] && j==y[s]) 14 flag=true; 15 if(flag) 16 continue; 17 for(int s=0;s<k;s++) 18 if(vis[x[s]][y[s]] && abs(i-x[s])+abs(j-y[s])<=r[s]){ 19 flag=true; 20 break; 21 } 22 if(!flag) 23 return false; 24 } 25 return true; 26 } 27 int main() 28 { 29 while(scanf("%d",&n)==1 && n){ 30 scanf("%d",&k); 31 int minnum=100; 32 for(int i=0;i<k;i++) 33 scanf("%d%d",&x[i],&y[i]); 34 for(int i=0;i<k;i++) 35 scanf("%d",&r[i]); 36 for(int i=0;i<(1<<k);i++){ 37 int num=0; 38 memset(vis,0,sizeof(vis)); 39 for(int j=0;j<k;j++){ 40 if(i&(1<<j)){ 41 vis[x[j]][y[j]]=1; 42 num++; 43 } 44 } 45 if(solve() && minnum>num) 46 minnum=num; 47 } 48 if(minnum==100) 49 printf("-1\n"); 50 else 51 printf("%d\n",minnum); 52 } 53 return 0; 54 }