洛谷P1034 矩形覆盖

题目

做法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);
}

猜你喜欢

转载自blog.csdn.net/xumingyang0/article/details/80560372
今日推荐