hdu 4462 构造子集+枚举

来源:互联网 发布:淘宝被恶意退款 编辑:程序博客网 时间:2024/06/05 12:44

Scaring the Birds

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2799    Accepted Submission(s): 880


Problem Description
It’s harvest season now!
Farmer John plants a lot of corn. There are many birds living around his corn field. These birds keep stealing his corn all the time. John can't stand with that any more. He decides to put some scarecrows in the field to drive the birds away.
John's field can be considered as an N×N grid which has N×N intersections. John plants his corn on every intersection at first. But as time goes by, some corn were destroyed by rats or birds so some vacant intersections were left. Now John wants to put scarecrows on those vacant intersections and he can put at most one scarecrow on one intersection. Because of the landform and the different height of corn, every vacant intersections has a scaring range R meaning that if John put a scarecrow on it, the scarecrow can only scare the birds inside the range of manhattan distance R from the intersection.



The figure above shows a 7×7 field. Assuming that the scaring range of vacant intersection (4,2) is 2, then the corn on the marked intersections can be protected by a scarecrow put on intersection (4,2).
Now John wants to figure out at least how many scarecrows he must buy to protect all his corn.
 

Input
There are several test cases.
For each test case:
The first line is an integer N ( 2 <= N <= 50 ) meaning that John's field is an N×N grid.
The second line is an integer K ( 0<= K <= 10) meaning that there are K vacant intersections on which John can put a scarecrow.
The third line describes the position of K vacant intersections, in the format of r1,c1,r2,c2 …. rK,ck . (ri,ci) is the position of the i-th intersection and 1 <= r1,c1,r2,c2 …. rK,ck <= N.
The forth line gives the scaring range of all vacant intersections, in the format of R1,R2…RK and 0 <= R1,R2…RK <= 2 × N.
The input ends with N = 0.
 

Output
For each test case, print the minimum number of scarecrows farmer John must buy in a line. If John has no way to protect all the corn, print -1 instead.
 

Sample Input
422 2 3 31 3422 2 3 31 40
 

Sample Output
-11

分析:看到这题,我就想,因为有一些空点,选择一些最少的空点按照曼哈顿距离来覆盖其他田地点,这不就是生成子集来依次生成空点的一个集合,看一下集合中的空点能否把其他点全部覆盖,因为数据50*50*10,三次循环应该可以,于是就去写了.结果交了n次WA,无奈搜题解,然后看到一个思路相同的,就看着也差不多啊,于是就按照他的改,改了m次,又WA了m次,TMD,最后发现是我构造子集写错了,哎,真是一个悲伤的故事,构造子集还有一种写法是增量构造法,就是每次迭出一个元素放到集合中,如果用这种方法,那么一旦找到一个空点集合可以覆盖其他点,那么直接break,就好,这样会更快吧。方法差不多,就不在写了。看来要写一篇子集生成的总结啊,哎。。。

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int maxn=60;const int maxm=12;const int INF=1000000;int r[maxm],c[maxm];int R[maxm];bool f[maxn][maxn];int a[maxm];int n,k,ans;void init(){    scanf("%d",&k);    for(int i=0;i<k;i++){        scanf("%d%d",&r[i],&c[i]);    }    for(int i=0;i<k;i++){        scanf("%d",&R[i]);    }    ans=INF;}void solve(){    for(int i=0;i<(1<<k);i++){        int p=0;        for(int j=0;j<k;j++){            if(i&(1<<j))a[p++]=j;        }        memset(f,false,sizeof(f));        for(int x=1;x<=n;x++){            for(int y=1;y<=n;y++){                for(int z=0;z<k;z++){                    if(x==r[z]&&y==c[z])                        f[x][y]=true;                }            }        }        bool flag=true;        for(int x=1;x<=n;x++){            for(int y=1;y<=n;y++){                if(!f[x][y]){                    for(int z=0;z<p;z++){                        if(abs(x-r[a[z]])+abs(y-c[a[z]])<=R[a[z]]){                            f[x][y]=true;                            break;                        }                    }                }                if(!f[x][y]){flag=false;break;}            }            if(!flag)break;        }        if(!flag)continue;        ans=min(ans,p);    }}int main(){    while(scanf("%d",&n)==1&&n){        init();        solve();        if(ans>20)ans=-1;        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击