Cake slicing
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 544 Accepted Submission(s): 282
Problem Description
A rectangular cake with a grid of m*n unit squares on its top needs to be sliced into pieces. Several cherries are scattered on the top of the cake with at most one cherry on a unit square. The slicing should follow the rules below:
- each piece is rectangular or square;
- each cutting edge is straight and along a grid line;
- each piece has only one cherry on it;
- each cut must split the cake you currently cut two separate parts
For example, assume that the cake has a grid of 3*4 unit squares on its top, and there are three cherries on the top, as shown in the figure below.
One allowable slicing is as follows.
For this way of slicing , the total length of the cutting edges is 2+4=6.
Another way of slicing is
In this case, the total length of the cutting edges is 3+2=5.
Give the shape of the cake and the scatter of the cherries , you are supposed to find
out the least total length of the cutting edges.
Input
The input file contains multiple test cases. For each test case:
The first line contains three integers , n, m and k (1≤n, m≤20), where n*m is the size of the unit square with a cherry on it . The two integers show respectively the row number and the column number of the unit square in the grid .
All integers in each line should be separated by blanks.
Output
Output an integer indicating the least total length of the cutting edges.
Sample Input
3 4 3
1 2
2 3
3 2
Sample Output
Case 1: 5
其中,dp[x1][y1][x2][y2]dp[x1][y1][x2][y2]dp[x1][y1][x2][y2]表示矩形(左上角(x1,y1),右下角(x2,y2))的切割线长度。
#include<iostream>
#include<cstring>
using namespace std;
#define inf 0x3f3f3f3f
int n,m,k;
int a[25][25];
int dp[25][25][25][25];
int dfs(int x1,int y1,int x2,int y2) { //(x1,y1)到(x2,y2)
int ans=dp[x1][y1][x2][y2];
if(ans!=-1) return ans;
int cnt=0;
for(int i=x1; i<=x2; i++) {
for(int j=y1; j<=y2; j++) {
if(a[i][j]==1) {
cnt++;
}
}
}
if(cnt==0) {
dp[x1][y1][x2][y2]=inf;
return inf;
}else if(cnt==1){
dp[x1][y1][x2][y2]=0;
return 0;
}
ans=inf;
for(int i=x1;i<x2;i++){
ans=min(ans,dfs(x1,y1,i,y2)+dfs(i+1,y1,x2,y2)+y2-y1+1);
}
for(int i=y1;i<y2;i++){
ans=min(ans,dfs(x1,y1,x2,i)+dfs(x1,i+1,x2,y2)+x2-x1+1);
}
dp[x1][y1][x2][y2]=ans;
return ans;
}
int main() {
int x,y;
int cas=0;
while(cin>>n>>m>>k) {
cas++;
memset(a,0,sizeof(a));
for(int i=0; i<k; i++) {
cin>>x>>y;
a[x][y]=1;
}
memset(dp,-1,sizeof(dp));
cout<<"Case "<<cas<<": "<<dfs(1,1,n,m)<<endl;
}
return 0;
}