题目大意:平面坐标上有n个点,你可以讲任意两点作为矩形的斜对角线上的两点,问你当所有点都被矩形覆盖之后,矩形总面积最少是多少;
题目解析:这肯定是状态dp,但这里我们不能枚举点,我们应该枚举矩形,但矩形的形式是以点构成的集合,所以开始我们要处理出所有矩形的可能性,枚举第i个点和第j个点为边界构成的矩形时,应该再扫一遍点,把矩形包含的点也加进去;
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#define inf 0x3fffffff
using namespace std;
struct poin
{
int x,y;
};
struct rect
{
int array;
int area;
rect(int a,int b)
{
array=a;
area=b;
}
void add(int a)
{
array=array|(1<<a);
}
};
poin point[20];
vector<rect>vec;
int dp[(1<<15)+10];
int check(int a,int b,int c)
{
if((point[a].x-point[c].x)*(point[b].x-point[c].x)<=0&&(point[a].y-point[c].y)*(point[b].y-point[c].y)<=0)
return 1;
else
return 0;
}
int main()
{
int n,i,j,k,len;
while(scanf("%d",&n)!=EOF&&n)
{
vec.clear();
for(i=0;i<n;i++)
{
scanf("%d%d",&point[i].x,&point[i].y);
}
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
rect temp((1<<i)|(1<<j),max(1,abs(point[i].x-point[j].x))*max(1,abs(point[i].y-point[j].y)));
for(k=0;k<n;k++)
{
if(check(i,j,k))
{
temp.add(k);
}
}
vec.push_back(temp);
}
}
len=1<<n;
for(i=0;i<len;i++)
dp[i]=inf;
dp[0]=0;
for(i=0;i<len;i++)
{
for(j=0;j<vec.size();j++)
{
dp[i|(vec[j].array)]=min(dp[i|(vec[j].array)],dp[i]+vec[j].area);
}
}
printf("%d\n",dp[len-1]);
}
return 0;
}