Description
You are given a rectangular cake of integral dimensions w × h. Your goal is to divide this cake into m rectangular pieces of integral dimensions such that the area of the largest piece is minimal. Each cut must be a straight line parallel to one of the sides of the original cake and must divide a piece of cake into two new pieces of positive area. Note that since a cut divides only a single piece, exactly m−1 cuts are needed.
Examples
If w = 4, h = 4, and m = 4, then the following cuts minimize the area of the largest piece:
However, if w = 4, h = 4, and m = 3, then the following cuts are optimal:
Input
The input test file will contain multiple test cases, each of which consists of three integers w, h, m separated by a single space, with 1 <= w, h,m <= 20 and m <= wh. The end-of-file is marked by a test case with w = h = m = 0 and should not be processed.
Output
For each test case, write a single line with a positive integer indicating the area of the largest piece.
Sample Input
4 4 4 4 4 3 0 0 0
Sample Output
4 6
总之要想办法构造出状态转移方程,这道题是:
记忆化搜索,dp[k][i][j]为将一块i*j的蛋糕切k刀的最大面积的最小值,枚举下一刀的横竖以及切的位置和其中一份的刀数
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
int dp[405][25][25];
int dfs(int m,int w,int h)
{
if(dp[m][w][h]!=inf)
return dp[m][w][h];
else if(m==0)
return dp[m][w][h]=w*h;
else
{
int ans=inf;
for(int i=1,lim=w/2+1;i<=lim;i++)
for(int k=0;k<=m-1;k++)
ans=min(ans,max(dfs(k,i,h),dfs(m-1-k,w-i,h)));
for(int i=1,lim=h/2+1;i<=lim;i++)
for(int k=0;k<=m-1;k++)
ans=min(ans,max(dfs(k,w,i),dfs(m-1-k,w,h-i)));
return dp[m][w][h]=ans;
}
}
int main()
{
int w,h,m;
memset(dp,0x3f,sizeof(dp));
while(scanf("%d%d%d",&w,&h,&m),w||h||m)
printf("%d\n",dfs(m-1,w,h));
return 0;
}