Lazy Cows
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 1897 | Accepted: 718 |
Description
Farmer John regrets having applied high-grade fertilizer to his pastures since the grass now grows so quickly that his cows no longer need to move around when they graze. As a result, the cows have grown quite large and lazy... and winter is approaching.
Farmer John wants to build a set of barns to provide shelter for his immobile cows and believes that he needs to build his barns around the cows based on their current locations since they won't walk to a barn, no matter how close or comfortable.
The cows' grazing pasture is represented by a 2 x B (1 <= B <= 15,000,000) array of cells, some of which contain a cow and some of which are empty. N (1 <= N <= 1000) cows occupy the cells in this pasture:
Ever the frugal agrarian, Farmer John would like to build a set of just K (1 <= K <= N) rectangular barns (oriented with walls parallel to the pasture's edges) whose total area covers the minimum possible number of cells. Each barn covers a rectangular group of cells in their entirety, and no two barns may overlap. Of course, the barns must cover all of the cells containing cows.
By way of example, in the picture above if K=2 then the optimal solution contains a 2x3 barn and a 1x4 barn and covers a total of 10 units of area.
Farmer John wants to build a set of barns to provide shelter for his immobile cows and believes that he needs to build his barns around the cows based on their current locations since they won't walk to a barn, no matter how close or comfortable.
The cows' grazing pasture is represented by a 2 x B (1 <= B <= 15,000,000) array of cells, some of which contain a cow and some of which are empty. N (1 <= N <= 1000) cows occupy the cells in this pasture:
------------------------------------------------------- | | cow | | | | cow | cow | cow | cow | ------------------------------------------------------- | | cow | cow | cow | | | | | | -------------------------------------------------------
Ever the frugal agrarian, Farmer John would like to build a set of just K (1 <= K <= N) rectangular barns (oriented with walls parallel to the pasture's edges) whose total area covers the minimum possible number of cells. Each barn covers a rectangular group of cells in their entirety, and no two barns may overlap. Of course, the barns must cover all of the cells containing cows.
By way of example, in the picture above if K=2 then the optimal solution contains a 2x3 barn and a 1x4 barn and covers a total of 10 units of area.
Input
* Line 1: Three space-separated integers, N, K, and B.
* Lines 2..N+1: Two space-separated integers in the range (1,1) to (2,B) giving the coordinates of the cell containing each cow. No cell contains more than one cow.
* Lines 2..N+1: Two space-separated integers in the range (1,1) to (2,B) giving the coordinates of the cell containing each cow. No cell contains more than one cow.
Output
* Line 1: The minimum area required by the K 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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std;
struct LCow{
int x, y;
}cow[1010];
int f[1010][1010][4];
int N, K, M;
int cmp(LCow a, LCow b){
return a.x < b.x;
}
int min4(int a, int b, int c, int d){
if (a > b) a = b;
if (a > c) a = c;
if (a > d) a = d;
return a;
}
int main(){
int i, j, k, t;
while(scanf("%d%d%d", &N, &K, &M) != EOF){
for (i = 1; i <= N; i++)
scanf("%d%d", &cow[i].y, &cow[i].x);
sort(cow + 1, cow + 1 + N, cmp);
memset(f, 0x0f, sizeof(f));
cow[0].x = 0;
if (2 <= N && cow[1].x == cow[2].x){
f[1][1][0] = f[2][1][0] = 2;
f[1][2][3] = f[2][2][3] = 2;
}else{
f[1][1][0] = f[1][2][3] = 2;
f[1][1][cow[1].y] = 1;
}
for (k = 1; k <= K; k++){
for (i = 1; i <= N; i++){
if (k - 2 < 0) j = 0x0f0f0f0f;
else{
j = min4(
f[i - 1][k - 2][0],
f[i - 1][k - 2][1],
f[i - 1][k - 2][2],
f[i - 1][k - 2][3]);
}
t = min4(
f[i - 1][k - 1][3],
f[i - 1][k - 1][0],
f[i - 1][k - 1][1],
f[i - 1][k - 1][2]);
f[i][k][0] = min(f[i][k][0], min(
f[i - 1][k][0] + 2 * (cow[i].x - cow[i - 1].x),
t + 2));
f[i][k][3] = min(f[i][k][3], min4(
f[i - 1][k][3] + 2 * (cow[i].x - cow[i - 1].x),
f[i - 1][k - 1][1] + cow[i].x - cow[i - 1].x + 1,
f[i - 1][k - 1][2] + cow[i].x - cow[i - 1].x + 1,
j + 2));
if (i + 1 <= N && cow[i].x == cow[i + 1].x){
f[i + 1][k][0] = f[i][k][0];
f[i + 1][k][3] = f[i][k][3];
i++;
}else if (cow[i].y == 1){
f[i][k][1] = min(f[i][k][1], min4(
f[i - 1][k][1] + cow[i].x - cow[i - 1].x,
t + 1,
f[i - 1][k][3] + cow[i].x - cow[i - 1].x,
0x0f0f0f0f));
}else{
f[i][k][2] = min(f[i][k][2], min4(
f[i - 1][k][2] + cow[i].x - cow[i - 1].x,
t + 1,
f[i - 1][k][3] + cow[i].x - cow[i - 1].x,
0x0f0f0f0f));
}
// printf("f[%d][%d] = %d, %d, %d, %d\n", k, i, f[i][k][1], f[i][k][2], f[i][k][0], f[i][k][3]);
}
}
t = min4(f[N][K][0], f[N][K][1], f[N][K][2], f[N][K][3]);
printf("%d\n", t);
}
return 0;
}
/*
f[i][j][1] 前i只牛,放到j个barn中, j是上行
f[i][j][2] 前i只牛,放到j个barn中, j是下行
f[i][j][3] 前i只牛,放到j个barn中, j是双行
f[i][j][4] 前i只牛,放到j个barn中,j是单行但双barn
如果i和i+1在同一列
f[i+1][j][1] = f[i+1][j][2] = INF;
f[i+1][j][0] = min(
f[i-1][j][0]+2*(cow[i].x-cow[i-1].x),
f[i-1][j-1][0..3]+2)
f[i+1][j][3] = min(
f[i-1][j][3]+2*(cow[i].x-cow[i-1].x),
f[i-1][j-1][1]+cow[i].x-cow[i-1].x +1,
f[i-1][j-1][2]+cow[i].x-cow[i-1].x +1,
f[i-1][j-2][0..3]+2)
如果i在上行
f[i][j][1] = min(
f[i-1][j][1]+cow[i].x-cow[i-1].x,
f[i-1][j][3]+cow[i].x-cow[i-1].x +1,
f[i-1][j-1][0..3]+1)
f[i][j][2] = INF
f[i][j][0] 同上
f[i][j][3] 同上
如果i在下行
f[i][j][2] = min(
f[i-1][j][2]+cow[i].x-cow[i-1].x,
f[i-1][j][3]+cow[i].x-cow[i-1].x +1,
f[i-1][j-1][0..3]+1)
f[i][j][1] = INF
其他同上
初值赋的很暴力,先把所有设为无效
再枚举几种可能出现的初值做基础,没想到的反正也无效的...
其实状态1,2可以何为一个
http://hi.baidu.com/creamxcream/blog/item/d1288a8e93f5cdf7513d9237.html
这个跑的很快32MS
*/