题意:有n头牛在2*b的牧场上,只可以修建k(k<=n)个矩形牛棚,牛棚之间不能有重叠的部分,求牛棚的最小面积。
分析:用dp[i][j][l]表示前i列的牛都铺满,用去啦j个帐篷,状态为l,的最小面积。
l==0,表示没有铺
l==1,表示铺啦第一格
l==2,表示铺啦第二格
l==3,表示铺啦一二格,且不在一个矩形里。
l==4,表示铺啦一二格,且在一个矩形里。
ACcode
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int dp[1010][1010][5],n,k,m,b[1010][2];
struct edge
{
int x,l;
bool operator<(const edge &c)const
{
return x<c.x;
}
}a[1010];
int main()
{
while(scanf("%d%d%d",&n,&k,&m)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].l,&a[i].x);
}
sort(a+1,a+n+1);
int n2=1;
for(int i=2;i<=n;i++)
{
if(a[i].x!=a[i-1].x)
a[++n2]=a[i];
else
a[n2].l=3;
}
n=n2;
//cout<<n<<endl;
memset(b,0,sizeof(b));
for(int i=1;i<=n;i++)
{
if(a[i].l==1)
b[i][1]=1;
else if(a[i].l==2)
b[i][2]=1;
else
{
b[i][1]=b[i][2]=1;
}
}
memset(dp,50,sizeof(dp));
dp[0][0][0]=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<=k;j++)
{
for(int l=0;l<5;l++)
{
if(!b[i+1][2])
dp[i+1][j+1][1]=min(dp[i+1][j+1][1],dp[i][j][l]+1);
if(!b[i+1][1])
dp[i+1][j+1][2]=min(dp[i+1][j+1][2],dp[i][j][l]+1);
dp[i+1][j+2][3]=min(dp[i+1][j+2][3],dp[i][j][l]+2);
dp[i+1][j+1][4]=min(dp[i+1][j+1][4],dp[i][j][l]+2);
if(l==1)
{
if(!b[i+1][2])
dp[i+1][j][1]=min(dp[i+1][j][1],dp[i][j][1]+a[i+1].x-a[i].x);
else
dp[i+1][j+1][3]=min(dp[i+1][j+1][3],dp[i][j][1]+a[i+1].x-a[i].x+1);
}
else if(l==2)
{
if(!b[i+1][1])
dp[i+1][j][2]=min(dp[i+1][j][2],dp[i][j][2]+a[i+1].x-a[i].x);
else
dp[i+1][j+1][3]=min(dp[i+1][j+1][3],dp[i][j][2]+a[i+1].x-a[i].x+1);
}
else if(l==3)
{
if(!b[i+1][2])
dp[i+1][j][1]=min(dp[i+1][j][1],dp[i][j][3]+a[i+1].x-a[i].x);
else
dp[i+1][j+1][3]=min(dp[i+1][j+1][3],dp[i][j][3]+a[i+1].x-a[i].x+1);
if(!b[i+1][1])
dp[i+1][j][2]=min(dp[i+1][j][2],dp[i][j][3]+a[i+1].x-a[i].x);
else
dp[i+1][j+1][3]=min(dp[i+1][j+1][3],dp[i][j][3]+a[i+1].x-a[i].x+1);
dp[i+1][j][3]=min(dp[i+1][j][3],dp[i][j][3]+2*(a[i+1].x-a[i].x));
}
else if(l==4)
{
dp[i+1][j][4]=min(dp[i+1][j][4],dp[i][j][4]+2*(a[i+1].x-a[i].x));
}
}
}
}
int ans=INF;
for(int i=0;i<=k;i++)
{for(int l=0;l<5;l++)
{
//cout<<dp[n][i][l]<<" ";
ans=min(ans,dp[n][i][l]+k-i);
}//cout<<endl;
}printf("%d\n",ans);
}
return 0;
}