zoukankan      html  css  js  c++  java
  • POJ 2836 Rectangular Covering(状压DP)

    【题目链接】 http://poj.org/problem?id=2836

    【题目大意】

      给出二维平面的一些点,现在用一些非零矩阵把它们都包起来,
      要求这些矩阵的面积和最小,求这个面积和

    【题解】

      我们计算出以每两个点为矩形顶点所构成的矩形面积和包含的点子集,
      然后对这些子集进行状态DP,求全集的最小覆盖

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <cstring>
    using namespace std;
    const int N=16;
    int n,dp[1<<N],x[N],y[N];
    struct Rect{
        int coverd,area;
        Rect(const int& coverd,const int& area):coverd(coverd),area(area){}
        void add(int i){coverd|=1<<i;} 
    };
    bool in(int i,int j,int k){return((x[i]-x[k])*(x[j]-x[k])<=0)&&((y[i]-y[k])*(y[j]-y[k])<=0);}
    int main(){
        while(scanf("%d",&n)&&n){
            for(int i=0;i<n;i++)scanf("%d%d",&x[i],&y[i]);
            vector<Rect> VR;
            for(int i=0;i<n;i++){
                for(int j=i+1;j<n;j++){
                    Rect r((1<<i)|(1<<j),max(1,abs(x[i]-x[j]))*max(1,abs(y[i]-y[j])));
                    if(i!=j)for(int k=0;k<n;k++)if(in(i,j,k))r.add(k);  
                    VR.push_back(r);
                }
            }memset(dp,0x3f,sizeof(dp));
            dp[0]=0; vector<Rect>::iterator it;
            for(it=VR.begin();it!=VR.end();it++){
                for(int s=0;s<(1<<n);s++){
                    int ns=s|it->coverd;
                    if(ns!=s)dp[ns]=min(dp[ns],dp[s]+it->area);
                }
            }printf("%d
    ",dp[(1<<n)-1]);
        }return 0;
    }
  • 相关阅读:
    [HAOI2015]按位或
    CF451E Devu and Flowers
    [APIO2017]商旅
    后缀自动机总结
    [HNOI2011]括号修复 / [JSOI2011]括号序列
    [WC2021] 括号路径
    批处理系列(3)
    SQL关于子集中有NULL的问题解析
    SQL排除满足同时多个条件的记录行
    SQLServer 通过导入数据的形式复制数据库
  • 原文地址:https://www.cnblogs.com/forever97/p/poj2836.html
Copyright © 2011-2022 走看看