poj 2430 Lazy Cows

题目链接:http://poj.org/problem?id=2430

题目大意及思路:用最多k个矩形覆盖所有的牛,且要使总面积最小,做法是将两行压缩成一行并进行离散化,对于每一列有四种状态,而在dp的时候也有四种状态,1、只覆盖上面,2、只覆盖下面,3、上下用一个矩形覆盖,4、上下用两个矩形覆盖。这样就可以写出转移方程了。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<queue>
#include<algorithm>
#include<vector>
#include<stack>
#include<list>
#include<iostream>
#include<map>
using namespace std;
#define inf 0x3f3f3f3f
#define Max 110
int max(int a,int b)
{
	return a>b?a:b;
}
inline int min(int a,int b)
{
	return a<b?a:b;
}
int pos[1010],n,k,b;
int s[1010],dp[1010][1010][4];
struct node
{
    int x,y;
    bool operator<(const node b)const
    {
        if(y==b.y)
            return x<b.x;
        return y<b.y;
    }
}a[1010];
int main()
{
    int i,j,l,cnt;
    while(scanf("%d%d%d",&n,&k,&b)!=EOF)
    {
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&a[i].x,&a[i].y);
        }
        cnt=1;
        sort(a+1,a+n+1);
        memset(s,0,sizeof(s));
        pos[cnt]=a[1].y;
        if(a[1].x==1)
            s[cnt]=0;
        else
            s[cnt]=1;
        for(i=2;i<=n;i++)
        {
            if(a[i].y==a[i-1].y)
            {
                s[cnt]=2;
                continue;
            }
            cnt++;
            pos[cnt]=a[i].y;
            if(a[i].x==1)
                s[cnt]=0;
            else
                s[cnt]=1;
        }
    //    for(i=1;i<=cnt;i++)
      //      printf("i %d s %d\n",i,s[i]);
      //  pos[0]=pos[1]-1;
        for(i=0;i<=cnt;i++)
            for(j=0;j<=k;j++)
                for(l=0;l<4;l++)
                    dp[i][j][l]=inf;
        dp[0][0][2]=0;
        for(i=1;i<=cnt;i++)
        {
            for(j=1;j<=k;j++)
            {
                int tmp2;
                int tmp=min(min(dp[i-1][j-1][0],dp[i-1][j-1][1]),min(dp[i-1][j-1][2],dp[i-1][j-1][3]));
                if(j>=2)
                  tmp2=min(min(dp[i-1][j-2][0],dp[i-1][j-2][1]),min(dp[i-1][j-2][2],dp[i-1][j-2][3]));
                if(s[i]==0)
                {
                    dp[i][j][0]=min(tmp+1,min(dp[i-1][j][0],dp[i-1][j][3])+pos[i]-pos[i-1]);
                    dp[i][j][2]=min(tmp+2,dp[i-1][j][2]+(pos[i]-pos[i-1])*2);
                    dp[i][j][3]=min(dp[i-1][j][3]+2*(pos[i]-pos[i-1]),min(dp[i-1][j-1][0],dp[i-1][j-1][1])+pos[i]-pos[i-1]+1);
                    if(j>=2)
                        dp[i][j][3]=min(tmp2+2,dp[i][j][3]);
                }
                else if(s[i]==1)
                {
                     dp[i][j][1]=min(tmp+1,min(dp[i-1][j][1],dp[i-1][j][3])+pos[i]-pos[i-1]);
                     dp[i][j][2]=min(tmp+2,dp[i-1][j][2]+(pos[i]-pos[i-1])*2);
                     dp[i][j][3]=min(dp[i-1][j][3]+2*(pos[i]-pos[i-1]),min(dp[i-1][j-1][0],dp[i-1][j-1][1])+pos[i]-pos[i-1]+1);
                     if(j>=2)
                        dp[i][j][3]=min(tmp2+2,dp[i][j][3]);
                }
                else
                {
                    dp[i][j][2]=min(tmp+2,dp[i-1][j][2]+(pos[i]-pos[i-1])*2);
                    dp[i][j][3]=min(dp[i-1][j][3]+2*(pos[i]-pos[i-1]),min(dp[i-1][j-1][0],dp[i-1][j-1][1])+pos[i]-pos[i-1]+1);
                    if(j>=2)
                        dp[i][j][3]=min(tmp2+2,dp[i][j][3]);
                }
             //   for(l=0;l<4;l++)
              //  printf("i %d j %d l %d dp %d\n",i,j,l,dp[i][j][l]);
            }

        }
        int ans=inf;
        for(j=0;j<4;j++)
        {
            ans=min(ans,dp[cnt][k][j]);
        }
        printf("%d\n",ans);
    }
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值