题目链接: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); } }