HDU 4462

状态压缩,K<=10, 0--2^k-1的二进制每一位对应第K个稻草人是否放(0表示不放,1表示放)

注意稻草人坑是不需要覆盖的,全是坑的时候,输出0;(不要问我为什么知道,因为我被坑了4次   T_T)

#include <iostream>
#include <string.h>
using namespace std;
struct pos{
  int x,y;
}p[15];
int f[55][55],r[15];
int n,k;
int abs(int a){
    if(a<0)return -a;
    return a;
}
void change(int b){                        //用于把第b个稻草人所包括的范围覆盖
    int xx,yy;
    int l=r[b];
    for(int i=-l;i<=l;i++){
        xx=p[b].x+i;
        if(xx<1||xx>n)continue;
        for(int j=abs(i)-l;j<=l-abs(i);j++){
            yy=p[b].y+j;
            if(yy<1||yy>n)continue;
            f[yy][xx]=1;
        }
    }
}
void init(){                                    //初始化
    memset(f,0,sizeof(f));
    for(int i=0;i<k;i++){
        f[p[i].y][p[i].x]=1;
    }
}
bool solve(){                                    //检验是否所有的田地都已经覆盖
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(!f[i][j])return false;
        }
    }
    return true;
}
int main(){
    int ans,flag;
    while(cin>>n){
        if(n==0)break;
        cin>>k;
        for(int i=0;i<k;i++){
            cin>>p[i].y>>p[i].x;
        }
        for(int i=0;i<k;i++){
            cin>>r[i];
        }
        ans=k+1;
        init();
        if(solve()){cout<<"0"<<endl;}                              //都是坑时直接输出0;
        else {
            for(int i=0;i<(1<<k);i++){
                flag=0;
                init();
                for(int j=0;j<k;j++){
                    if(i&1<<j){                                    //状态压缩
                        change(j);          
                        flag++;
                    }
                }
                if(solve()){
                    if(ans>flag)ans=flag;
                }
            }
            if(ans<=k)cout<<ans<<endl;
            else cout<<"-1"<<endl;
        }
    }
}

posted @ 2014-07-21 16:13  Mr.XuJH  阅读(158)  评论(0编辑  收藏  举报