做法1:dp
官方题解
s[i][j]表示:以i和j为两个顶点的矩形面积
f[i][j][k]表示:k个矩形,覆盖了点i和点j之间所有点的矩形的最小面积
#include<bits/stdc++.h>
using namespace std;
struct kk{
int x,y;
}a[52];
int s[52][52],f[52][52][6],n,m,i,ans;
bool cmp(kk x,kk y){
return x.x<y.x || x.x==y.x && x.y<y.y;
}
int high(int l,int r){
int mx=0,mn=1e4;
for (int i=l;i<=r;i++) mx=max(mx,a[i].y),mn=min(mn,a[i].y);
return mx-mn;
}
void dp(){
sort(a+1,a+m+1,cmp);
for (int i=1;i<=m;i++)
for (int j=1;j<=m;j++)
for (int k=1;k<=n;k++) f[i][j][k]=1e6;
for (int i=1;i<=m;i++)
for (int j=i;j<=m;j++) f[i][j][1]=s[i][j]=(a[j].x-a[i].x)*high(i,j);
for (int p=1;p<=m;p++)
for (int i=1;i<=m-p;i++)
for (int k=2,j=i+p;k<=n;k++)
for (int t=i;t<j;t++) f[i][j][k]=min(f[i][j][k],f[i][t][k-1]+s[t+1][j]);
ans=min(ans,f[1][m][n]);
}
int main(){
scanf("%d%d",&m,&n);
for (i=1;i<=m;i++) scanf("%d%d",&a[i].x,&a[i].y);
a[m+1].x=1e4;a[m+1].y=1e4;
ans=1e9;
dp();
for (i=1;i<=m;i++) swap(a[i].x,a[i].y);
dp();
printf("%d",ans);
}
做法2:搜索
题解
标程:
#include<bits/stdc++.h>
using namespace std;
struct dot{
int x,y;
}a[51];
struct M{
int l,r,u,d;
bool fl;
}p[5];
int n,m,ans=1e9,i;
bool in(M a,int x,int y){
return x>=a.l && x<=a.r && y>=a.d && y<=a.u;
}
bool judge(M a, M b){
return in(a,b.l,b.u) || in(a,b.l,b.d) || in(a,b.r,b.u) || in(a,b.r,b.d);
}
void dfs(int num){
int val=0;
for (int i=1;i<=m;i++){
if (p[i].fl)
for (int j=i+1;j<=m;j++)
if (judge(p[i],p[j])) return;
val+=(p[i].r-p[i].l)*(p[i].u-p[i].d);
}
if (val>=ans) return;
if (num>n){
ans=val;
return;
}
for (int i=1;i<=m;i++){
M tmp=p[i];
if (!p[i].fl){
p[i].fl=1;
p[i].l=p[i].r=a[num].x;
p[i].u=p[i].d=a[num].y;
dfs(num+1);
p[i]=tmp;
break;
}
else{
p[i].r=max(p[i].r,a[num].x);
p[i].l=min(p[i].l,a[num].x);
p[i].u=max(p[i].u,a[num].y);
p[i].d=min(p[i].d,a[num].y);
dfs(num+1);
p[i]=tmp;
}
}
}
int main(){
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
dfs(1);
printf("%d",ans);
}