POJ-2430:Lazy Cows

来源:互联网 发布:自动抢红包软件 编辑:程序博客网 时间:2024/06/05 18:57

Lazy Cows
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 2734 Accepted: 1049

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: 
-------------------------------------------------------|     | 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.

Output

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

Sample Input

8 2 91 21 61 71 81 92 22 32 4

Sample Output

10

思路:用d[i][k][j]表示最小面积。前i列用k个barn,j=1表示最后一个barn只建在第一行,j=2表示只建在第2行,j=3表示2行都建且属于一个barn的,j=4表示2行都建但属于2个不同的barn。

#include<iostream>#include<cstring>#include<cmath>#include<algorithm>#include<cstdio>using namespace std;struct lenka{    long long x,y;}a[10000],b[10000];int cmp(const lenka& x,const lenka& y){    if(x.y==y.y)return x.x<y.x;    return x.y<y.y;}long long d[1001][1001][5];int main(){    int n,k,L;    while(cin>>n>>k>>L)    {        for(int i=0;i<n;i++)scanf("%lld%lld",&a[i].x,&a[i].y);        sort(a,a+n,cmp);        int MAX=1;        for(int i=0;i<n;)        //把不同列的选出来        {            if(i+1<n&&a[i+1].y==a[i].y)//找到同一列的            {                b[MAX].x=a[i].y;                b[MAX++].y=3;                i+=2;            }            else            {                b[MAX].x=a[i].y;                b[MAX++].y=a[i].x;                i++;            }           // printf("第%lld列 %lld行\n",b[MAX-1].x,b[MAX-1].y);        }        memset(d,0x3f3f3f3f,sizeof d);        d[0][0][3]=0;        for(int i=1;i<MAX;i++)        {            for(int j=1;j<=k;j++)            {                long long A,B;                A=min(min(d[i-1][j-1][1],d[i-1][j-1][2]),min(d[i-1][j-1][3],d[i-1][j-1][4]));                if(j>=2)B=min(min(d[i-1][j-2][1],d[i-1][j-2][2]),min(d[i-1][j-2][3],d[i-1][j-2][4]));                if(b[i].y==1)   //只有第一行有牛                {                    d[i][j][1]=min(d[i][j][1],A+1);                    d[i][j][1]=min(d[i][j][1],d[i-1][j][1]+b[i].x-b[i-1].x);//延长之前的barn                    d[i][j][1]=min(d[i][j][1],d[i-1][j][4]+b[i].x-b[i-1].x);                }                else if(b[i].y==2) //只有第二行有牛                {                    d[i][j][2]=min(d[i][j][2],A+1);                    d[i][j][2]=min(d[i][j][2],d[i-1][j][2]+b[i].x-b[i-1].x);                    d[i][j][2]=min(d[i][j][2],d[i-1][j][4]+b[i].x-b[i-1].x);                }                d[i][j][3]=min(d[i][j][3],A+2);                d[i][j][3]=min(d[i][j][3],d[i-1][j][3]+2ll*(b[i].x-b[i-1].x));                d[i][j][4]=min(min(d[i-1][j-1][1],d[i-1][j-1][2])+b[i].x-b[i-1].x+1,d[i-1][j][4]+2ll*(b[i].x-b[i-1].x));                if(j>=2)d[i][j][4]=min(d[i][j][4],B+2);            }        }        cout<<min(min(d[MAX-1][k][1],d[MAX-1][k][2]),min(d[MAX-1][k][3],d[MAX-1][k][4]))<<endl;    }    return 0;}





原创粉丝点击