分蛋糕
Posted 路人姜。
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分蛋糕相关的知识,希望对你有一定的参考价值。
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
有一块矩形大蛋糕,长和宽分别是整数w 、h。现要将其切成m块小蛋糕,每个小蛋糕都必须是矩形、且长和宽均为整数。切蛋糕时,每次切一块蛋糕,将其分成两个矩形蛋糕。请计算:最后得到的m块小蛋糕中,最大的那块蛋糕的面积下限。
假设w= 4, h= 4, m= 4,则下面的切法可使得其中最大蛋糕块的面积最小。
假设w= 4, h= 4, m= 3,则下面的切法会使得其中最大蛋糕块的面积最小:
- 输入
- 共有多行,每行表示一个测试案例。每行是三个用空格分开的整数w, h, m ,其中1 ≤ w, h, m ≤ 20 , m ≤ wh. 当 w = h = m = 0 时不需要处理,表示输入结束。
- 输出
- 每个测试案例的结果占一行,输出一个整数,表示最大蛋糕块的面积下限。
- 样例输入
-
4 4 4 4 4 3 0 0 0
- 样例输出
-
4 6
- 来源:openjudge
- 参考代码
/** 一看就是按递归的思想转换成动规 dp[w][h][m],w:长h:宽m:块数 表示长w宽h的蛋糕切m刀所能得到最大块蛋糕面积的最小值 边界条件: ①w*h<m,dp[w][h][m]=INF(最多w*h块,每块都分成1的大小,所以不会超过m块) ②m=1,dp[w][h][1]=w*h 每一刀,看是横切,还是竖切 取切后的最大块中最小的 假设初始蛋糕左右是长上下是宽 得到的小块蛋糕继续切,直到切完m-1刀 */ ///代码摘自:http://www.cnblogs.com/candy99/p/5792478.html #include <iostream> #include <cstring> using namespace std; const int N=22,INF=1e9; int f[N][N][N],w,h,m; void solve(){ memset(f,0,sizeof(f)); //边界条件 for(int i=1;i<=w;i++) for(int j=1;j<=h;j++) f[i][j][1]=i*j; for(int i=1;i<=w;i++) for(int j=1;j<=h;j++) for(int k=2;k<=min(i*j,m);k++){ f[i][j][k]=INF; //横切 for(int t=1;t<i;t++){ for(int p=1;p<k;p++) f[i][j][k]=min(f[i][j][k],max(f[t][j][p],f[i-t][j][k-p])); } //竖切 for(int t=1;t<j;t++){ for(int p=1;p<k;p++) f[i][j][k]=min(f[i][j][k],max(f[i][t][p],f[i][j-t][k-p])); } } } int main(int argc, const char * argv[]) { while(cin>>w>>h>>m){ if(w==0&&h==0&&m==0) break; solve(); cout<<f[w][h][m]<<"\\n"; } return 0; }
该题一看就能知道用DP,可是实现起来有点复杂,我也没有彻底搞明白,欢迎推荐更详细,更易懂的题解,感激不尽!
以上是关于分蛋糕的主要内容,如果未能解决你的问题,请参考以下文章