60 条题解
- 
  1aph。 (chenqianrong) LV 10 @ 2021-08-27 12:12:31 #include<bits/stdc++.h> using namespace std; #define N 55 int n,k,x[N],y[N],ans=INT_MAX>>2; struct mat{ int lx,ly,rx,ry; bool cnt; void add(int x, int y){ if(!cnt){ lx=rx=x; ly=ry=y; cnt = 1; } else{ if(x<lx) lx = x; else if(x>rx) rx = x; if(y>ly) ly = y; else if(y<ry) ry = y; } } bool inmat(int x, int y) const { return lx<=x && x<=rx && ry<=y && y<=ly; } int operator() () { if(!cnt) return 0; return (rx-lx)*(ly-ry); } bool operator* (const mat &o){ if(!cnt || !o.cnt) return 0; return o.inmat(lx, ly) || o.inmat(lx, ry) || o.inmat(rx, ly) || o.inmat(rx, ry); } }km[5]; bool check(){ for(int i=1; i<=k; i++) for(int j=i+1; j<=k; j++) if(km[i]*km[j]) return 0; return 1; } void dfs(int i,int area) { if(area>=ans) return; if(i==n){ if(check()) if(ans>area) ans=area; return; } mat tmp; for(int j=1; j<=k; j++){ tmp=km[j]; km[j].add(x[i],y[i]); dfs(i+1,area-tmp()+km[j]()); km[j]=tmp; } } int main() { cin>>n>>k; for(int i=0; i<n; i++) scanf("%d%d",x+i,y+i); dfs(0,0); cout<<ans; return 0; }
- 
  1@ 2018-09-22 20:53:38DFS+分支界限法剪枝 
 虽然是很套路的题,但写了好久好久……实在是想不到“各个矩形必须完全分开”的简单实现方式,所以代码的内容越来越多……#include <iostream> #include <cstdlib> #include <cstring> #include <stack> #include <algorithm> #define MAX 100000000 #define NLIMIT 50 #define KLIMIT 4 using namespace std; int n,k,ans=MAX; struct node { int area; int num;//即将要选的点 int re[KLIMIT][NLIMIT-KLIMIT+1];//点的顺序号 int p[KLIMIT];//点的数目 int maxx[KLIMIT]; int minx[KLIMIT]; int maxy[KLIMIT]; int miny[KLIMIT]; node():area(0),num(0) { for(int i=0;i<KLIMIT;i++) { p[i]=0; minx[i]=MAX; miny[i]=MAX; } memset(re,-1,sizeof(re)); memset(maxx,-1,sizeof(maxx)); memset(maxy,-1,sizeof(maxy)); } }; stack<node> st; void DFS(int x[],int y[]) { node t; st.push(t); while(st.empty()==false) { t=st.top(); st.pop(); if(t.area>ans)//优化剪枝 continue; if(t.num==n) { int flag=1; for(int i=0;i<k;i++) if(t.p[i]==0) { flag=0; break; } if(flag==0) continue; else ans=min(ans,t.area); } else for(int i=0;i<k;i++) { node aot=t; aot.re[i][t.p[i]]=t.num; aot.p[i]=t.p[i]+1; aot.num=t.num+1; aot.maxx[i]=max(aot.maxx[i],x[t.num]); aot.maxy[i]=max(aot.maxy[i],y[t.num]); aot.minx[i]=min(aot.minx[i],x[t.num]); aot.miny[i]=min(aot.miny[i],y[t.num]); int flag=1; for(int j=0;j<k-1;j++) if(aot.p[j]!=0) { for(int q=j+1;q<k;q++) if(aot.p[q]!=0) { if(aot.maxx[j]>=aot.minx[q]&&aot.maxx[j]<=aot.maxx[q]&&aot.maxy[j]<=aot.maxy[q]&&aot.maxy[j]>=aot.miny[q]) flag=0; else if(aot.maxx[q]>=aot.minx[j]&&aot.maxx[q]<=aot.maxx[j]&&aot.maxy[q]<=aot.maxy[j]&&aot.maxy[q]>=aot.miny[j]) flag=0; else if(aot.maxx[j]>=aot.minx[q]&&aot.maxx[j]<=aot.maxx[q]&&aot.maxy[q]<=aot.maxy[j]&&aot.maxy[q]>=aot.miny[j]) flag=0; else if(aot.maxx[q]>=aot.minx[j]&&aot.maxx[q]<=aot.maxx[j]&&aot.maxy[j]<=aot.maxy[q]&&aot.maxy[j]>=aot.miny[q]) flag=0; if(flag==0) break; } if(flag==0) break; } if(flag==0) continue; aot.area=0; for(int q=0;q<k;q++) if(aot.p[q]!=0) aot.area+=(aot.maxx[q]-aot.minx[q])*(aot.maxy[q]-aot.miny[q]); st.push(aot); } } } int main() { cin>>n>>k; int x[n],y[n]; for(int i=0;i<n;i++) cin>>x[i]>>y[i]; DFS(x,y); cout<<ans<<endl; return 0; }
- 
  0@ 2018-08-08 08:27:12审题要仔细啊 各个矩形之间不能相交 #include <bits/stdc++.h> using namespace std; #define FOR(i,n) for (int i=1;i<=n;i++) #define REP(i,a,b) for (int i=a;i<=b;i++) #define pb push_back #define mp make_pair #define ll long long const int N=10000+10; const int inf=0x3f3f3f3f; const ll mod=7654321; const double PI=3.1415926; const double eps=1e-8; int n,m; int x[100],y[100]; int b[100]; int sum; bool empty[5]; int c[5][5]; int ans=inf; bool intersect(int a,int b) { int xx,yy; for (int i=1;i<=3;i+=2) { for (int j=2;j<=4;j+=2) { xx=c[b][i],yy=c[b][j]; if (c[a][1]<=xx&&xx<=c[a][3]) if (c[a][4]<=yy&&yy<=c[a][2]) return 1; } } return 0; } void dfs(int a) { if (a==n+1) { ans=min(ans,sum); return; } FOR(i,m) { b[a]=i; memset(empty,1,sizeof empty); FOR(j,m) c[j][1]=c[j][4]=inf,c[j][2]=c[j][3]=-inf; FOR(j,a) { empty[b[j]]=0; c[b[j]][1]=min(c[b[j]][1],x[j]); c[b[j]][2]=max(c[b[j]][2],y[j]); c[b[j]][3]=max(c[b[j]][3],x[j]); c[b[j]][4]=min(c[b[j]][4],y[j]); } bool ok=1; FOR(j,m) if (!empty[j]) FOR(jj,m) if (!empty[jj]) if (jj!=j) if (intersect(j,jj)) { ok=0; break; } if (!ok) continue; sum=0; FOR(j,m) if (!empty[j]) { sum+=(c[j][2]-c[j][4])*(c[j][3]-c[j][1]); } if (sum>ans) continue; dfs(a+1); } } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); cin>>n>>m; FOR(i,n) cin>>x[i]>>y[i]; dfs(1); cout<<ans<<endl; return 0; }
- 
  0@ 2018-06-03 22:11:37AC200纪念!普普通通的 DFS+剪枝 就可以AC 
 May the father of understanding guide U.
- 
  0@ 2016-06-18 15:49:42枚举点在第几个矩形这个思路很好诶~~稍微剪一下枝就可以了~~ 
 ```c++
 #include<cstdio>
 #include<algorithm>
 #include<vector>
 #include<cstring>
 using namespace std;
 const int INF = 2147483647;struct Rec 
 {
 int top,left,lower,right,size;
 bool isempty;
 Rec(int a=0,int b=0,int c=0,int d=0,int e=0,bool f=true) : top(a),left(b),lower(c),right(d),size(e),isempty(f) {};
 void size_update(){ size=(top-lower)*(right-left); }
 };struct Po 
 {
 int x,y;
 Po(int a=0,int b=0) : x(a),y(b) {};
 bool operator< (const Po &a) const { return x<a.x || (x==a.x&&y<a.y); }
 };vector<Po> points; 
 Rec rectangles[5];
 int n,k,ans=INF;inline int is_inside(int now) 
 {
 int t=0;
 for(int i=1;i<=k;i++)
 if(!rectangles[i].isempty&&points[now].x>=rectangles[i].left&&points[now].x<=rectangles[i].right&&points[now].y>=rectangles[i].lower&&points[now].y<=rectangles[i].top) t++;
 return t;
 }void dfs(int now) 
 {
 if(now==n)
 {
 int t=0;
 for(int i=1;i<=k;i++)
 if(!rectangles[i].isempty) t+=rectangles[i].size;
 ans=min(t,ans);
 return;
 }int t=0; 
 for(int i=1;i<=k;i++)
 if(!rectangles[i].isempty) t+=rectangles[i].size;
 if(t>=ans) return;if(is_inside(now)) {dfs(now+1);return;} 
 for(int i=1;i<=k;i++)
 {
 Rec temp=rectangles[i];
 if(rectangles[i].isempty)
 {
 rectangles[i].isempty=false;
 rectangles[i].left=rectangles[i].right=points[now].x;
 rectangles[i].top =rectangles[i].lower=points[now].y;
 rectangles[i].size_update();
 dfs(now+1);
 }
 else
 {
 if(points[now].x<rectangles[i].left) rectangles[i].left=points[now].x;
 else if(points[now].x>rectangles[i].right) rectangles[i].right=points[now].x;
 if(points[now].y>rectangles[i].top) rectangles[i].top=points[now].y;
 else if(points[now].y<rectangles[i].lower) rectangles[i].lower=points[now].y;
 rectangles[i].size_update();bool failed=false; 
 for(int j=0;j<now;j++)
 if(is_inside(j)>1) { failed=true;break; }
 if(!failed) dfs(now+1);
 }
 rectangles[i]=temp;
 }
 }int main() 
 {
 scanf("%d%d",&n,&k);
 for(int i=1;i<=n;i++)
 {
 int a,b;
 scanf("%d%d",&a,&b);
 points.push_back(Po(a,b));
 }
 sort(points.begin(),points.end());dfs(0); 
 printf("%d\n",ans);
 return 0;
 }
 ```
- 
  0@ 2015-12-28 22:40:47总算AC了。0ms。 
 说说思路:
 1. 枚举每个矩形的边界(只需枚举两个顶点即可)。O( k^(n*n) )
 2. 枚举每个点属于哪个矩形。O( n^k )一开始用思路一来做,超时+莫名其妙的1个WA 
 改用思路2,秒杀。具体说来就是每次枚举点加入哪个矩形内,并把矩形相应扩大(也可能不扩大),递归搜索,搜完回来再恢复原始状态。注意的是每个矩形需要一个 isEmpty 标志,这样往里面加入第一个点的时候才不会出错。#include <stdio.h> 
 #include <stdlib.h>
 #include <limits.h>#define MAX(a,b) ((a)>(b)?(a):(b)) 
 #define MIN(a,b) ((a)<(b)?(a):(b))typedef struct{ 
 short isEmpty;
 int l, r, t, b; //left, right, top, bottom
 } RECT;
 typedef struct{
 int x, y;
 } POINT;int numPoint, numRect; 
 int minArea = LONG_MAX;
 POINT point[55];
 RECT rect[5];void dfs(int index, int area); 
 int intersect(RECT a, RECT b);
 int verify();int main(){ 
 int i;scanf("%d %d", &numPoint, &numRect); 
 for(i=0; i<numPoint; i++)
 scanf("%d %d", &point[i].x, &point[i].y);
 for(i=0; i<numRect; i++)
 rect[i].isEmpty = 1;
 dfs(0, 0);
 printf("%d\n", minArea);return 0; 
 }
 int intersect(RECT a, RECT b){ //see: http://blog.csdn.net/yahohi/article/details/7927158
 int dx, dy;
 dx = abs((a.r+a.l) - (b.r+b.l));
 dy = abs((a.t+a.b) - (b.t+b.b));
 if(dx <= a.r-a.l + b.r-b.l && dy <= a.t-a.b + b.t-b.b)
 return 1;
 return 0;
 }
 int verify(){ //if any two rectangles intersect, return false
 int i, k;
 for(i=0; i<numRect; i++){
 if(rect[i].isEmpty)
 continue;
 for(k=i+1; k<numRect; k++){
 if(rect[k].isEmpty)
 continue;
 if(intersect(rect[i], rect[k]))
 return 0;
 }
 }
 return 1;
 }
 void dfs(int index, int area){
 int i, delta;
 RECT tmp;
 if(area >= minArea)
 return;
 if(index == numPoint){
 for(i=0; i<numRect; i++){
 if(rect[i].isEmpty)
 return;
 }
 minArea = area;
 return;
 }
 for(i=0; i<numRect; i++){
 tmp = rect[i];
 if(rect[i].isEmpty){
 rect[i].l = rect[i].r = point[index].x;
 rect[i].b = rect[i].t = point[index].y;
 rect[i].isEmpty = 0;
 }else{
 rect[i].l = MIN(rect[i].l, point[index].x);
 rect[i].r = MAX(rect[i].r, point[index].x);
 rect[i].b = MIN(rect[i].b, point[index].y);
 rect[i].t = MAX(rect[i].t, point[index].y);
 }
 if(verify()){
 delta = (rect[i].r-rect[i].l) * (rect[i].t-rect[i].b); //new area
 delta -= (tmp.r-tmp.l) * (tmp.t-tmp.b); //-= original area
 dfs(index+1, area+delta);
 }
 rect[i] = tmp;
 }
 }
- 
  0@ 2015-09-11 23:57:12记录信息 评测状态 Accepted 
 题目 P1126 矩形覆盖
 递交时间 2015-09-11 23:56:25
 代码语言 C++
 评测机 VijosEx
 消耗时间 17 ms
 消耗内存 564 KiB
 评测时间 2015-09-11 23:56:27评测结果 编译成功 测试数据 #0: Accepted, time = 0 ms, mem = 564 KiB, score = 10 测试数据 #1: Accepted, time = 15 ms, mem = 560 KiB, score = 10 测试数据 #2: Accepted, time = 2 ms, mem = 564 KiB, score = 10 测试数据 #3: Accepted, time = 0 ms, mem = 560 KiB, score = 10 测试数据 #4: Accepted, time = 0 ms, mem = 564 KiB, score = 10 Accepted, time = 17 ms, mem = 564 KiB, score = 50 代码 #include <iostream> 
 #include <stdio.h>
 #include <string.h>
 #include <algorithm>using namespace std; int f[50 + 2][50 + 2][5]; 
 int n , k , i;struct point 
 {
 int x , y;
 };point p[50 + 2]; int dp( int l , int r , int k ) 
 {
 if( l > r )
 return 0;
 if( !k )
 return 100000000;
 if( k == 1 && f[l][r][k] == -1 )
 {
 if( l == r )
 return 0;
 int i , minx , miny , maxx , maxy;
 minx = miny = 10000000;
 maxx = maxy = 0;
 for( i = l ; i <= r ; i++ )
 {
 minx = min( minx , p[i].x );
 miny = min( miny , p[i].y );
 maxx = max( maxx , p[i].x );
 maxy = max( maxy , p[i].y );
 }
 return f[l][r][k] = ( maxx - minx ) * ( maxy - miny );
 }
 if( f[l][r][k] != -1 )
 return f[l][r][k];
 f[l][r][k] = 100000000;
 int i , j;
 for( i = l - 1 ; i <= r ; i++ )
 for( j = 0 ; j <= k ; j++ )
 f[l][r][k] = min( dp( l , i , j ) + dp( i + 1 , r , k - j ) , f[l][r][k] );
 return f[l][r][k];
 }inline int cmp( point a , point b ) 
 {
 if( a.y < b.y )
 return 1;
 if( a.y == b.y )
 if( a.x < b.x )
 return 1;
 return 0;
 }int main() 
 {
 scanf( "%d %d" , &n , &k );
 for( i = 1 ; i <= n ; i++ )
 scanf( "%d %d" , &p[i].x , &p[i].y );
 sort( p + 1 , p + n + 1 , cmp );
 memset( f , -1 , sizeof( f ) );
 cout << dp( 1 , n , k ) << endl;
 return 0;
 }
 DP加上脏防卡AC的飞起
- 
  0@ 2015-07-05 13:40:51放心做吧,裸搜都不会超时! var 
 n,k,i:longint;
 x:array[0..51,1..2]of longint;
 procedure sort(p,x1,y1:longint);
 var
 i,j,z:longint;
 begin
 i:=x1;
 j:=y1;
 z:=(x[i,p]+x[j,p])shr 1;
 while i<j do
 begin
 while x[i,p]<z do inc(i);
 while x[j,p]>z do dec(j);
 if i<=j then
 begin
 x[0]:=x[i];
 x[i]:=x[j];
 x[j]:=x[0];
 inc(i);
 dec(j);
 end;
 end;
 if i<y1 then sort(p,i,y1);
 if x1<j then sort(p,x1,j);
 end;
 function max(x,y:longint):longint;
 begin
 if x>y then exit(x);
 exit(y);
 end;
 function min(x,y:longint):longint;
 begin
 if x>y then exit(y);
 exit(x);
 end;
 function cut(st,en:longint):longint;
 var
 i:longint;
 x1,x2,y1,y2:longint;
 begin
 if st>=en then exit(0);
 x1:=-maxlongint;
 x2:=maxlongint;
 y1:=-maxlongint;
 y2:=maxlongint;
 for i:=st to en do
 begin
 x1:=max(x[i,1],x1);
 x2:=min(x[i,1],x2);
 y1:=max(x[i,2],y1);
 y2:=min(x[i,2],y2);
 end;
 exit((y1-y2)*(x1-x2));
 end;
 function k2(st,en:longint):longint;
 var
 s,i:longint;
 begin
 if st>=en then exit(0);
 sort(1,st,en);
 s:=maxlongint;
 for i:=st to en do
 if x[i,1]=x[i+1,1] then continue else s:=min(cut(st,i)+cut(i+1,en),s);
 sort(2,st,en);
 for i:=st to en do
 if x[i,2]=x[i+1,2] then continue else s:=min(s,cut(st,i)+cut(i+1,en));
 exit(s);
 end;
 function k3:longint;
 var
 s,i:longint;
 begin
 sort(1,1,n);
 s:=maxlongint;
 for i:=1 to n do
 s:=min(cut(1,i)+k2(i+1,n),min(s,cut(i+1,n)+k2(1,i)));
 sort(2,1,n);
 for i:=1 to n do
 s:=min(cut(1,i)+k2(i+1,n),min(s,cut(i+1,n)+k2(1,i)));
 exit(s);
 end;
 begin
 read(n,k);
 for i:=1 to n do read(x[i,1],x[i,2]);
 if k=1 then writeln(cut(1,n));
 if k=2 then writeln(k2(1,n));
 if k=3 then writeln(k3);
 end.
- 
  0@ 2014-10-05 07:37:44type rectangle=record 
 xl,xr,yu,yd:longint;
 end;
 arr=array[1..4] of rectangle;var a:arr; 
 px,py:array[1..50] of longint;
 b:array[1..50] of boolean;
 n,i,min,k,s,ss,tot,sb:longint;function maxnum(a,b:longint):longint; 
 begin
 maxnum:=a;
 if a<b then
 maxnum:=b;
 end;function minnum(a,b:longint):longint; 
 begin
 minnum:=a;
 if a>b then
 minnum:=b;
 end;function area(var t:rectangle):longint; 
 begin
 with t do
 exit((xr-xl)*(yu-yd));
 end;function pointinit(var x,y:longint; var t:rectangle):boolean; 
 begin
 with t do
 if (x>=xl)and(x<=xr)and(y>=yd)and(y<=yu) then
 exit(true)
 else
 exit(false);
 end;function cover(var t:rectangle):longint; 
 var i:longint;
 begin
 cover:=0;
 for i:=1 to n do
 if not b[i] and pointinit(px[i],py[i],t) then
 begin
 b[i]:=true;
 inc(cover);
 end;
 end;procedure discover(var t,r:rectangle); 
 var i:longint;
 begin
 for i:=1 to n do
 if b[i] and pointinit(px[i],py[i],t) and not pointinit(px[i],py[i],r) then
 b[i]:=false;
 end;function check(x:longint; var a:arr):boolean; 
 var i:longint;
 begin
 with a[x] do
 for i:=1 to tot do
 begin
 if x<>i then
 if (maxnum(xl,a[i].xl)<=minnum(xr,a[i].xr))and(maxnum(yd,a[i].yd)<=minnum(yu,a[i].yu)) then
 exit(false);
 end;
 exit(true);
 end;function putpoint(x,y:longint; var t:rectangle):boolean; 
 begin
 putpoint:=false;
 with t do
 begin
 if (xl<0)or(xr<0)or(yu<0)or(yd<0) then
 begin
 xl:=x;
 xr:=x;
 yu:=y;
 yd:=y;
 inc(tot);
 exit(true);
 end;
 if x<xl then
 xl:=x;
 if x>xr then
 xr:=x;
 if y>yu then
 yu:=y;
 if y<yd then
 yd:=y;
 end;
 end;procedure search(ar,covered,pos:longint; a:arr); 
 var i,j:longint;
 t,x:rectangle;
 bo:boolean;
 begin
 if n-covered<k-tot then
 exit;
 if covered>=n then
 begin
 if ar<min then
 min:=ar;
 end
 else
 begin
 if not b[pos] then
 for i:=1 to minnum(tot+1,k) do
 begin
 t:=a[i];
 bo:=putpoint(px[pos],py[pos],a[i]);
 if check(i,a) then
 begin
 s:=area(a[i])-area(t);
 ss:=cover(a[i]);
 search(ar+s,covered+ss,pos+1,a);
 discover(a[i],t);
 end;
 if bo then
 dec(tot);
 a[i]:=t;
 end
 else
 search(ar,covered,pos+1,a);
 end;
 end;begin 
 readln(n,k);
 for i:=1 to n do
 readln(px[i],py[i]);
 min:=maxlongint;
 tot:=0;
 for i:=1 to k do
 begin
 a[i].xl:=-1;
 a[i].xr:=-1;
 a[i].yu:=-1;
 a[i].yd:=-1;
 end;
 search(0,0,1,a);
 writeln(min);
 end.
- 
  0@ 2014-08-10 15:19:23#include<iostream> 
 #include<cmath>
 #include<cstdlib>
 #include<cstring>
 #include<cstdio>
 #include<algorithm>
 #include<vector>
 #include<queue>#define M 101 
 #define INF 0x7fffffffusing namespace std; int n,m; 
 int fx[M],fy[M];
 int minxx=INF;struct node 
 {
 int minx;
 int miny;
 int maxx;
 int maxy;
 }str1[M];void init() 
 {
 scanf("%d%d",&n,&m);
 for(int i=1;i<=n;i++)
 {
 int x,y;
 scanf("%d%d",&x,&y);
 fx[i]=x;
 fy[i]=y;
 }
 for(int i=1;i<=m;i++)
 {
 str1[i].minx=1000;
 str1[i].miny=1000;
 str1[i].maxx=-100;
 str1[i].maxy=-100;
 }
 }int com() 
 {
 int flag=0;
 for(int i=1;i<=m;i++)
 for(int j=1;j<=m;j++)
 if(i!=j)
 {
 if(str1[i].minx>=str1[j].minx&&str1[i].minx<=str1[j].maxx&&str1[i].miny>=str1[j].miny&&str1[i].miny<=str1[j].maxy)
 flag=1;
 if(str1[i].minx>=str1[j].minx&&str1[i].minx<=str1[j].maxx&&str1[i].maxy>=str1[j].miny&&str1[i].maxy<=str1[j].maxy)
 flag=1;
 if(str1[i].maxx>=str1[j].minx&&str1[i].maxx<=str1[j].maxx&&str1[i].miny>=str1[j].miny&&str1[i].miny<=str1[j].maxy)
 flag=1;
 if(str1[i].maxx>=str1[j].minx&&str1[i].maxx<=str1[j].maxx&&str1[i].maxy>=str1[j].miny&&str1[i].maxy<=str1[j].maxy)
 flag=1;
 }
 int sum=0;
 for(int i=1;i<=m;i++)
 {
 if(str1[i].minx==1000&&str1[i].miny==1000&&str1[i].maxx==-100&&str1[i].maxy==-100)
 sum=sum+0;
 else
 sum=sum+(str1[i].maxx-str1[i].minx)*(str1[i].maxy-str1[i].miny);
 }
 if(sum>=minxx)
 flag=1;
 return flag;
 }void dfs(int no) 
 {
 if(com()==1)
 return ;
 if(no==n+1)
 {
 int flag=0;
 for(int i=1;i<=m;i++)
 for(int j=1;j<=m;j++)
 if(i!=j)
 {
 if(str1[i].minx>=str1[j].minx&&str1[i].minx<=str1[j].maxx&&str1[i].miny>=str1[j].miny&&str1[i].miny<=str1[j].maxy)
 flag=1;
 if(str1[i].minx>=str1[j].minx&&str1[i].minx<=str1[j].maxx&&str1[i].maxy>=str1[j].miny&&str1[i].maxy<=str1[j].maxy)
 flag=1;
 if(str1[i].maxx>=str1[j].minx&&str1[i].maxx<=str1[j].maxx&&str1[i].miny>=str1[j].miny&&str1[i].miny<=str1[j].maxy)
 flag=1;
 if(str1[i].maxx>=str1[j].minx&&str1[i].maxx<=str1[j].maxx&&str1[i].maxy>=str1[j].miny&&str1[i].maxy<=str1[j].maxy)
 flag=1;
 }
 for(int i=1;i<=m;i++)
 if(str1[i].minx>str1[i].maxx||str1[i].miny>str1[i].maxy)
 flag=1;
 if(flag==0)
 {
 int sum=0;
 for(int i=1;i<=m;i++)
 sum=sum+(str1[i].maxx-str1[i].minx)*(str1[i].maxy-str1[i].miny);
 minxx=min(minxx,sum);
 }
 }
 else
 for(int i=1;i<=m;i++)
 {
 int x1=str1[i].minx;
 int y1=str1[i].miny;
 int x2=str1[i].maxx;
 int y2=str1[i].maxy;
 if(fx[no]<str1[i].minx)
 str1[i].minx=fx[no];
 if(fx[no]>str1[i].maxx)
 str1[i].maxx=fx[no];
 if(fy[no]<str1[i].miny)
 str1[i].miny=fy[no];
 if(fy[no]>str1[i].maxy)
 str1[i].maxy=fy[no];
 dfs(no+1);
 str1[i].minx=x1;
 str1[i].miny=y1;
 str1[i].maxx=x2;
 str1[i].maxy=y2;
 }
 }int main() 
 {
 init();
 dfs(1);
 printf("%d\n",minxx);
 return 0;
 }
- 
  0@ 2013-11-06 21:46:46#include<cstdio> 
 #include<cstring>
 #include<iostream>
 #include<algorithm>
 #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;} 
- 
  0@ 2013-10-07 21:22:02procedure Dynamic; 
 var
 j,k,p:integer;
 s:array[1..50,1..50] of longint;
 f:array[1..50,1..50,1..4] of longint;
 begin
 for i:=1 to m do
 for j:=1 to m do
 for k:=1 to n do
 f[i,j,k]:=300000;
 for i:=1 to m do
 for j:=i to m do
 begin
 s[i,j]:=(x[j]-x[i])*hight(i,j);
 f[i,j,1]:=s[i,j];
 end;
 for p:=1 to m do
 for i:=1 to m-p do
 begin
 j:=i+p;
 for k:=2 to n do
 for t:=i to j-1 do
 f[i,j,k]:=min(f[i,j,k],f[i,t,k-1]+s[t+1,j]);
 end;
 ans:=min(ans,f[1,m,n]);
 end;
 begin
 readln(m,n);
 for i:=1 to m do
 readln(x[i],y[i]);
 x[m+1]:=maxint;y[m+1]:=maxint;
 ans:=maxlongint;
 sort(1,m);
 t:=x[1];last:=1;
 for i:=2 to m+1 do
 if x[i]<>t then
 begin
 qsort(last,i-1);
 t:=x[i];
 last:=i;
 end;
 Dynamic;
 for i:=1 to m do
 begin
 t:=x[i];
 x[i]:=y[i];
 y[i]:=t;
 end;
 sort(1,m);
 t:=x[1];last:=1;
 for i:=2 to m+1 do
 if x[i]<>t then
 begin
 qsort(last,i-1);
 t:=x[i];
 last:=i;
 end;
 Dynamic;
 writeln(ans);
 end.
- 
  0@ 2009-11-08 11:52:28编译通过... 
 ├ 测试数据 01:答案正确... 0ms
 ├ 测试数据 02:答案正确... 0ms
 ├ 测试数据 03:答案正确... 0ms
 ├ 测试数据 04:答案正确... 0ms
 ├ 测试数据 05:答案正确... 0ms
 ---|---|---|---|---|---|---|---|-
 Accepted 有效得分:100 有效耗时:0ms
- 
  0@ 2009-11-06 15:22:08编了60多行,搞得我头大。 
- 
  0@ 2009-11-06 11:19:58汗,自己机器上运行明明每个点都秒杀 
 结果同一个程序交上去,第一次两个点超时,第2次1个点超时,第三次全部超时,。。。
- 
  0@ 2009-11-04 16:01:28切分的方法有很多种,但是有些是重复的,可以通过旋转点的坐标减少判断的情况 
 最终 K=1时只有一种情况
 K=2时有也只有一种情况
 K=3时只有两种情况
 K=4时有五种划分的复杂度是 O(n^(K-1)),划分好了后算每一块面积是 O(K),总复杂度O(n^K) 此题最大为50^4,完全合适 #include 
 #include
 #include
 #include
 #include
 #include
 #include
 #include
 #include
 #include
 using namespace std;
 #define INF 2100000000
 #define MIN(A,B) ((A)(B)?(A):(B))
 #define ABS(A) ((A)
- 
  0@ 2009-11-01 21:15:01据说贪心都能过~ 
 我就一五一十枚举过去171行敝程序优点就是过程比较多,思路比较清晰 const maxn=1000000; 
 var n,k,i:longint;
 a,b:array[1..50] of longint;function min(x,y:longint):longint; 
 begin
 if x>y then exit(y) else exit(x);
 end;function min1(s,t:longint):longint; 
 var i:longint;
 begin
 min1:=maxn;
 for i:=s to t do if a[i]max2 then max2:=b[i];
 end;procedure soapa(s,t:longint); 
 var i,j,m:longint;
 begin
 for i:=s to t-1 do
 for j:=s to t-i do
 if a[j]>a[j+1] then
 begin
 m:=a[j];
 a[j]:=a[j+1];
 a[j+1]:=m;
 m:=b[j];
 b[j]:=b[j+1];
 b[j+1]:=m;
 end;
 end;procedure soapb(s,t:longint); 
 var i,j,m:longint;
 begin
 for i:=s to t-1 do
 for j:=s to t-i do
 if b[j]>b[j+1] then
 begin
 m:=a[j];
 a[j]:=a[j+1];
 a[j+1]:=m;
 m:=b[j];
 b[j]:=b[j+1];
 b[j+1]:=m;
 end;
 end;function g(s,t:longint):longint; 
 var x1,x2,y1,y2:longint;
 begin
 x1:=min1(s,t);
 x2:=max1(s,t);
 y1:=min2(s,t);
 y2:=max2(s,t);
 g:=(x2-x1)*(y2-y1);
 end;function g21(s,t:longint):longint; 
 var t1,t2,ans,i:longint;
 begin
 soapa(s,t);
 ans:=maxn;
 for i:=s to t-1 do
 begin
 t1:=g(s,i);
 t2:=g(i+1,t);
 if t1+t2
- 
  0@ 2009-10-23 15:31:31编译通过... 
 ├ 测试数据 01:答案正确... 0ms
 ├ 测试数据 02:答案正确... 0ms
 ├ 测试数据 03:答案正确... 0ms
 ├ 测试数据 04:答案正确... 0ms
 ├ 测试数据 05:答案正确... 0ms
 ---|---|---|---|---|---|---|---|-
 Accepted 有效得分:100 有效耗时:0ms
 ....1 time....
 Yeah!
- 
  0@ 2009-10-04 19:43:13看了这题目,没什么太大的想法,直接弱弱的想到快排+枚举..... 
 顺便判断了一下可能重合的情况,交上去,1遍AC........
 可是回头想想,发现好多情况还没考虑,程序压根就是错的......
 无语了,这样的数据....还是重头再做一次吧.....Ps:如果NOIP2009的数据也是~~ 
- 
  0@ 2009-09-10 11:48:41看了LRJ的报告200+的CODE我晕了…… 
 他用的切割法,K=3有5种切割……
 K=4有22种!!……
 (我很想知道如果K=4的话能用什么办法做。离散化么?)后来发现没有K=4,50^3还好没什么问题。