poj2836(状态压缩dp)

来源:互联网 发布:软件外部接口设计 编辑:程序博客网 时间:2024/05/17 09:03

链接:点击打开链接

题意:有n个点,用非零的矩形全覆盖住这些点,求所有矩形的面积和(重复部分重复算)

代码:

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;const int INF=0x3f3f3f3f;struct node{    int x,y;}a[20];int s[1<<20],dp[1<<20],area[1<<20];int main(){                                     //因为当面积最小时,一定是有是矩形俩那个顶点的点    int n,i,j,p,k;                              //因此两两分组枚举出所有情况    while(scanf("%d",&n)!=EOF&&n){        k=0;        memset(dp,INF,sizeof(dp));        memset(area,0,sizeof(area));        for(i=0;i<n;i++)        scanf("%d%d",&a[i].x,&a[i].y);        for(i=0;i<n;i++)        for(j=i+1;j<n;j++){            s[k]=(1<<i)|(1<<j);                 //s是每个矩形所含点的状态            for(p=0;p<n;p++){                   //area是当前状态的面积                if((a[p].x-a[i].x)*(a[p].x-a[j].x)<=0)                if((a[p].y-a[i].y)*(a[p].y-a[j].y)<=0){                    s[k]|=(1<<p);               //在当前矩形中,则直接添加进当前矩形                }            }            if(a[i].x==a[j].x)            area[k]=abs(a[i].y-a[j].y);            else if(a[i].y==a[j].y)            area[k]=abs(a[i].x-a[j].x);            else            area[k]=abs(a[i].x-a[j].x)*abs(a[i].y-a[j].y);            k++;        }        dp[0]=0;        for(i=0;i<(1<<n);i++)        for(j=0;j<k;j++)                        //求出所有状态的最小值        dp[i|s[j]]=min(dp[i|s[j]],dp[i]+area[j]);        printf("%d\n",dp[(1<<n)-1]);    }    return 0;}


 

0 0
原创粉丝点击