首先大家怒搜就好了,因为虽然说K<=4,实际上K是小于等于3的。
当然某些K<=3还600ms的我就不加评论了。
好吧,但是怎么搜呢?我们考虑到矩形数量很少,所以可以怒搜矩形。
一些神做法我在这里就先不说了,我先说一种简单好写,K=4也能过的沙茶做法。
我们可以开一个结构体存矩形,如:
struct Point{int x,y;}; int cmpx(Point a,Point b){return a.x<b.x;} int cmpy(Point a,Point b){return a.y<b.y;} struct Mrx { Point px[N],py[N]; int n; }mrx[10];
当然,lazy的我肯定没开这个pre数组,我利用K<=3的小性质直接传了一个参,说上一层哪个被拆了,然后快速水过,当K比较大时这是错的,看代码时不要吐槽~~,毕竟K就这么小。
然后怎么拆分呢?就是新开两个矩形,把旧矩形的点扔到新的两个矩形中,每次拆分的思想都是把x的域拆成两个,或者把y的域拆成两个。
太沙茶了,没看懂的赶紧看代码吧。
#include <cstdio> #include <cstring> #include <algorithm> #define N 55 #define inf 0x3f3f3f3f using namespace std; struct Point{int x,y;}; int cmpx(Point a,Point b){return a.x<b.x;} int cmpy(Point a,Point b){return a.y<b.y;} struct Mrx { Point px[N],py[N]; int n; }mrx[10]; int n,m,ans=inf; void dfs(int dep,int from) { int t_ans=0,i,j,k,to; int sta=max(1,dep-2<<1),end=dep*2-1; for(i=sta;i<=end;i++)if(i!=from)t_ans+=(mrx[i].px[mrx[i].n].x-mrx[i].px[1].x)*(mrx[i].py[mrx[i].n].y-mrx[i].py[1].y); ans=min(t_ans,ans); if(!ans)return ; if(dep==m)return ; for(i=sta;i<=end;i++)if(i!=from) { for(j=1;j<mrx[i].n;j++) { if(mrx[i].px[j].x!=mrx[i].px[j+1].x)/*切x*/ { to=dep*2; mrx[to].n=j; for(k=1;k<=mrx[to].n;k++) { mrx[to].px[k].x=mrx[to].py[k].x=mrx[i].px[k].x; mrx[to].px[k].y=mrx[to].py[k].y=mrx[i].px[k].y; } sort(mrx[to].px+1,mrx[to].px+mrx[to].n+1,cmpx); sort(mrx[to].py+1,mrx[to].py+mrx[to].n+1,cmpy); to=dep*2+1; mrx[to].n=mrx[i].n-j; for(k=1;k<=mrx[to].n;k++) { mrx[to].px[k].x=mrx[to].py[k].x=mrx[i].px[k+j].x; mrx[to].px[k].y=mrx[to].py[k].y=mrx[i].px[k+j].y; } sort(mrx[to].px+1,mrx[to].px+mrx[to].n+1,cmpx); sort(mrx[to].py+1,mrx[to].py+mrx[to].n+1,cmpy); dfs(dep+1,i); } if(mrx[i].py[j].y!=mrx[i].py[j+1].y)/*切y*/ { to=dep*2; mrx[to].n=j; for(k=1;k<=mrx[to].n;k++) { mrx[to].px[k].x=mrx[to].py[k].x=mrx[i].py[k].x; mrx[to].px[k].y=mrx[to].py[k].y=mrx[i].py[k].y; } sort(mrx[to].px+1,mrx[to].px+mrx[to].n+1,cmpx); sort(mrx[to].py+1,mrx[to].py+mrx[to].n+1,cmpy); to=dep*2+1; mrx[to].n=mrx[i].n-j; for(k=1;k<=mrx[to].n;k++) { mrx[to].px[k].x=mrx[to].py[k].x=mrx[i].py[k+j].x; mrx[to].px[k].y=mrx[to].py[k].y=mrx[i].py[k+j].y; } sort(mrx[to].px+1,mrx[to].px+mrx[to].n+1,cmpx); sort(mrx[to].py+1,mrx[to].py+mrx[to].n+1,cmpy); dfs(dep+1,i); } } } } int main() { // freopen("test.in","r",stdin); int i,j,k; int a,b,c; scanf("%d%d",&n,&m); mrx[1].n=n; for(i=1;i<=n;i++) { scanf("%d%d",&a,&b); mrx[1].px[i].x=mrx[1].py[i].x=a; mrx[1].px[i].y=mrx[1].py[i].y=b; } sort(mrx[1].px+1,mrx[1].px+n+1,cmpx); sort(mrx[1].py+1,mrx[1].py+n+1,cmpy); dfs(1,0); printf("%d\n",ans); return 0; }
来源:http://www.cnblogs.com/noip/archive/2012/08/13/2635815.html
#include<iostream> #define Max 1000000 using namespace std; int n,m,ans=Max,x[52],y[52],f[52][52][5]={0}; int High(int i,int j){ int maxh=0,minh=1000,temp=i; while(temp<=j) maxh=max(maxh,y[temp++]); temp=i; while(temp<=j) minh=min(minh,y[temp++]); return maxh-minh; } void Dp(){ for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) for(int k=2;k<=m;++k) f[i][j][k]=Max; for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) f[i][j][1]=(x[j]-x[i])*High(i,j); for(int i=1;i<=n;++i) for(int k=1;k<=m;++k) f[i][i][k]=0; for(int k=2;k<=m;++k) for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) for(int l=i+1;l<=j;++l) f[i][j][k]=min(f[i][j][k],f[i][l-1][k-1]+(x[j]-x[l])*High(l,j)); ans=min(ans,f[1][n][m]); } int main() { cin>>n>>m; for(int i=1;i<=n;++i) cin>>x[i]>>y[i]; for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) if(x[i]>x[j]) {swap(x[i],x[j]);swap(y[i],y[j]);} else if(x[i]==x[j]&&y[i]>=y[j]) swap(y[i],y[j]); Dp(); for(int i=1;i<=n;++i) swap(x[i],y[i]); for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) if(x[i]>x[j]) {swap(x[i],x[j]);swap(y[i],y[j]);} else if(x[i]==x[j]&&y[i]>=y[j]) swap(y[i],y[j]); Dp(); cout<<ans<<endl; return 0; }