poj2430 2010.7.31

来源:互联网 发布:什么听歌识曲软件好 编辑:程序博客网 时间:2024/06/11 04:15

Lazy Cows

Time Limit: 1000MS  Memory Limit: 65536K

Total Submissions: 1300  Accepted: 467

 

Description

 

Farmer John regrets having appliedhigh-grade fertilizer to his pastures since the grass now grows so quickly thathis cows no longer need to move around when they graze. As a result, the cowshave grown quite large and lazy... and winter is approaching.

 

Farmer John wants to build a set of barnsto provide shelter for his immobile cows and believes that he needs to buildhis barns around the cows based on their current locations since they won'twalk to a barn, no matter how close or comfortable.

 

The cows' grazing pasture is represented bya 2 x B (1 <= B <= 15,000,000) array of cells, some of which contain acow and some of which are empty. N (1 <= N <= 1000) cows occupy the cellsin this pasture:

 

-------------------------------------------------------

|    | cow |     |     |    | cow | cow | cow | cow |

-------------------------------------------------------

|    | cow | cow | cow |     |     |    |     |     |

-------------------------------------------------------

 

Ever the frugal agrarian, Farmer John wouldlike to build a set of just K (1 <= K <= N) rectangular barns (orientedwith walls parallel to the pasture's edges) whose total area covers the minimumpossible number of cells. Each barn covers a rectangular group of cells intheir entirety, and no two barns may overlap. Of course, the barns must coverall of the cells containing cows.

 

By way of example, in the picture above ifK=2 then the optimal solution contains a 2x3 barn and a 1x4 barn and covers atotal of 10 units of area.

Input

 

* Line 1: Three space-separated integers,N, K, and B.

 

* Lines 2..N+1: Two space-separatedintegers in the range (1,1) to (2,B) giving the coordinates of the cellcontaining each cow. No cell contains more than one cow.

Output

 

* Line 1: The minimum area required by theK barns in order to cover all of the cows.

Sample Input

 

8 2 9

1 2

1 6

1 7

1 8

1 9

2 2

2 3

2 4

 

Sample Output

 

10

 

Source

 

USACO 2005 U S Open Gold

 

题意简述:求用最少的矩形把给定的点完全覆盖。

 

解题思路:  状态dp。

设0表示值覆盖一格,1表示覆盖两格但是属于同一矩形,2表示覆盖两格不属于同一矩形。

 

首先把牛的坐标排序,方便按顺序处理。存在cow[i]中;

 

dp[i][j][p]:前i头牛,用j个矩形覆盖,在p状态下最少覆盖的格子数

先是边界条件  dp[1][1][0]=1;       dp[1][1][1]=2;  dp[1][1][2]=INF;        dp[1][2][2]=2;

 

p==0时 只覆盖一个格子

         1.j>1新添加的牛i重新开始一个矩形,min{dp[i-1][j-1][0..2]}+1

         2.i>j新添加的牛i和前面的牛们在同一个矩形中,

                   (1)若牛i和牛i-1在同一行,dp[i-1][j][0]+cow[i].y-cow[i-1].y(牛i和牛i-1的列坐标差);

                   (2)若不在同一行,dp[i-1][j][2]+cow[i].y-cow[i-1].y;

p==1时 覆盖的两个格子属于同一个矩形

         1.j>1新添加的牛i重新开始一个矩形,min{dp[i-1][j-1][0..2]}+2;

         2.i>j新添加的牛i和前面的牛们在同一个矩形中,dp[i-1][j][1]+2*(cow[i].y-cow[i-1].y);

p==2时 覆盖的两个格子属于不同的矩形

         1.j>2新添加的牛i重新开始2个矩形,min{dp[i-1][j-2][0..2]}+2;

         2.新添加的牛i和前面的牛们在同一个矩形中,

                   (1)j>1  dp[i-1][j-1][0]+cow[i].y-cow[i-1].y+1;

                   (2)i>j  dp[i-1][j][2]+2*(cow[i].y-cow[i-1].y);

 

Code  13588K 32MS 


#include <cstdio>#include <algorithm>using namespace std;#define MAXN  1010#define min(a,b) (a<b?a:b)#define INF (1<<30)struct type0{int x,y;}cow[MAXN];bool cmp(type0 a,type0 b){return a.y<b.y;}int dp[MAXN][MAXN][5];int n,k,b;void init(){scanf("%d%d%d",&n,&k,&b);for(int i=1;i<=n;i++)scanf("%d %d",&cow[i].x,&cow[i].y);sort(cow+1,cow+1+n,cmp);}void dpit(){dp[1][1][0]=1;dp[1][1][1]=2;dp[1][1][2]=INF;dp[1][2][2]=2;for(int i=2;i<=n;i++)for(int j=1;j<=k&&j<=i;j++)for(int p=0;p<3;p++){int temp=INF;switch (p){case 0:{if (j>1)for(int e=0;e<3;e++)temp=min(temp,dp[i-1][j-1][e]+1);if (i>j){int dis=cow[i].y-cow[i-1].y;if (cow[i].x==cow[i-1].x)temp=min(temp,dp[i-1][j][0]+dis);elsetemp=min(temp,dp[i-1][j][2]+dis);}break;};case 1:{if (j>1)for(int e=0;e<3;e++)temp=min(temp,dp[i-1][j-1][e]+2);if (i>j)temp=min(temp,dp[i-1][j][1]+(cow[i].y-cow[i-1].y)*2);break;};case 2:{if (j>2)for(int e=0;e<3;e++)temp=min(temp,dp[i-1][j-2][e]+2);int dis=cow[i].y-cow[i-1].y;if (j>1)temp=min(temp,dp[i-1][j-1][0]+dis+1);if (i>j)temp=min(temp,dp[i-1][j][2]+dis*2);break;};}dp[i][j][p]=temp;}}void outit(){int ans=INF;for(int i=0;i<3;i++)ans=min(ans,dp[n][k][i]);printf("%d\n",ans);}int main(){init();dpit();outit();return 0;}


0 0