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);
else
temp=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;
}