poj 2836 Rectangular Coverin

题目:http://poj.org/problem?id=2836

在一个二位平面内,有一些点,请用一些矩形来覆盖这些点,保证每个点至少被一个矩形覆盖,求矩形面积和的最小值。

因为要最小,所以每个矩形的一条对角线的两个顶点肯定是这些点,所以可以枚举出以i,j为顶点的矩形可以覆盖的集合,以及它的面积。需要注意的是,比如(1,1),(2,1),(3,1),(1,10)这组数据,很显然我们希望(1,1),(2,1),(3,1)被一个矩形覆盖,(1,10)被一个覆盖,但这时发现这两个矩形的面积好像都是0,这肯定是不行的,所以当我们想要覆盖的点在一条直线上时,应该把覆盖他们的矩形的宽置为1.


int n;
int a[20],b[20];
int all;
int dp[(1<<15)+5];
int Area[(1<<15)+5];
int res[(1<<15)+5],cnt;
inline void init(){
    clr(Area);
    rep(i,0,n){
        rep(j,i+1,n){
            int st=0;
            int x1=min(a[i],a[j]),x2=max(a[j],a[i]),y1=min(b[i],b[j]),y2=max(b[i],b[j]);
            int area;
            if(x2==x1) area=y2-y1;
            else if(y2==y1) area=x2-x1;
            else area=(x2-x1)*(y2-y1);
 
            rep(k,0,n){
                if(a[k]>=x1 && a[k]<=x2 && b[k]>=y1 && b[k]<=y2){
                    st |= (1<<k);
                }
            }
            res[cnt++]=st;
            Area[st]=area;
        }
    }
}
int main(){
    while(1){
        n=input();
        if(n==0) break;
        rep(i,0,n)   a[i]=input(),b[i]=input();
        all=(1<<n);
        cnt=0;
        init();
        rep(i,0,all) dp[i]=INF;
        dp[0]=0;
        rep(i,0,all){
            if(dp[i]!=INF){
                rep(j,0,cnt){
                    int jj=res[j];
                    if(Area[jj]!=-1){
                        int val=(i|jj);
                        dp[val]=min(dp[val],dp[i]+Area[jj]);
                    }
                }
            }
        }
        output(dp[all-1]);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值