题意:有一块n*n的田,田上有一些点可以放置稻草人,再给出一些稻草人,每个稻草人有其覆盖的距离ri,距离为曼哈顿距离,求要覆盖到所有的格子最少需要放置几个稻草人
由于稻草人数量很少,所以状态压缩枚举,之后慢慢判断即可,注意放稻草人的格子是不需要覆盖的
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=0x3f3f3f3f; 11 const double eps=1e-5; 12 #define cl(a) memset(a,0,sizeof(a)) 13 #define ts printf("***** "); 14 const int MAXN=1005; 15 int n,m,tt; 16 int x[MAXN],y[MAXN],r[MAXN],a[MAXN]; 17 int main() 18 { 19 int i,j,k; 20 #ifndef ONLINE_JUDGE 21 freopen("1.in","r",stdin); 22 #endif 23 while(scanf("%d",&n)!=EOF) 24 { 25 if(n==0) break; 26 scanf("%d",&k); 27 for(i=0;i<k;i++) scanf("%d%d",&x[i],&y[i]); 28 for(i=0;i<k;i++) scanf("%d",&r[i]); 29 int bit=(1<<k)-1; 30 int ans=1000000; 31 for(int s=0;s<=bit;s++) 32 { 33 int num=0; 34 for(j=0;j<k;j++) 35 { 36 if(s&(1<<j)) 37 { 38 a[num++]=j; //记录有放稻草人的格子 39 } 40 } 41 bool vis[MAXN][MAXN],flag=1; 42 cl(vis); 43 for(i=1;i<=n;i++) 44 { 45 for(j=1;j<=n;j++) 46 { 47 for(int d=0;d<k;d++) //没放稻草人的格子 48 { 49 if(i==x[d]&&j==y[d]) vis[i][j]=1; 50 } 51 for(int d=0;d<num;d++) 52 { 53 if(fabs(i-x[a[d]])+fabs(j-y[a[d]])<=r[a[d]]) //曼哈顿距离 54 { 55 vis[i][j]=1; 56 break; 57 } 58 } 59 if(vis[i][j]==0) //说明所有稻草人没法覆盖,该状态方案不可行 60 flag=0; 61 } 62 if(flag==0) break; //说明所有稻草人没法覆盖,该状态方案不可行 63 } 64 if(!flag)continue; 65 ans=min(ans,num); 66 } 67 if(ans>100000)ans=-1; 68 printf("%d ",ans); 69 } 70 }