HDU4462.Scaring the Birds(枚举子集+二进制表示状态)

https://vjudge.net/contest/369905#problem/D
题意:
在给定位置可以放稻草人,然后稻草人在一定范围内可以保护草地,要求至少要设置多少个稻草人才可以保护所有的草地
解题思路:
因为稻草人数量不大于10,所以可以直接枚举
稻草人的使用状况可以用二进制1到1<<k-1来表示,然后对于每一种状态进行n*n的讨论即可
特别要注意,稻草人的位置不需要覆盖,所以当k>=n *n的情况下要输出0

#include<cstdio>
#include<iostream>
#include<string.h>
using namespace std;
int n,k;
int ans=9999;
int vis[55][55];
int num[15];
int min(int a,int b)
{
	return a<b?a:b;
}
struct node
{
	int x,y,r;
}a[15];
bool judge(int x,int y,node a)
{
	if(abs(x-a.x)+abs(y-a.y)<=a.r)
		return true;
	else
		return false;
}
int main()
{
	while(scanf("%d",&n)!=EOF){
		if(n==0)
			break;
		ans=9999;
		memset(vis,0,sizeof(vis));
		scanf("%d",&k);
	for(int i=1;i<=k;i++)
	{
		scanf("%d%d",&a[i].x,&a[i].y);
		vis[a[i].x][a[i].y]=1;
	}
	for(int i=1;i<=k;i++)
		scanf("%d",&a[i].r);
	//特别注意k>=n*n的情况
	if(k>=n*n)
	{
		printf("0\n");
		continue;
	}
	int s=(1<<k)-1;
	for(int i=1;i<=s;i++)
	{
		memset(num,0,sizeof(num));
		int cnt=0;
		for(int j=0;j<k;j++)
			if(i&(1<<j))
				num[cnt++]=j+1;
		int res=0;
		for(int ii=1;ii<=n;ii++)
		{
			for(int jj=1;jj<=n;jj++)
			{
				if(vis[ii][jj]){
					res++;
					continue;
				}
				for(int kk=0;kk<cnt;kk++)
				{
					if(judge(ii,jj,a[num[kk]]))
					{
						res++;
						break;
					}
				}
			}
		}
		if(res==n*n)
		{
			ans=min(cnt,ans);
		}
	}
	if(ans!=9999)
		printf("%d\n",ans);
	else
		printf("-1\n");
	}
	return 0;
}



原创文章 65 获赞 3 访问量 2085

猜你喜欢

转载自blog.csdn.net/littlegoldgold/article/details/105764683