标签:面积 htm 测试 0ms 分享 pen 技术分享 最小值 log
有一块矩形大蛋糕,长和宽分别是整数w 、h。现要将其切成m块小蛋糕,每个小蛋糕都必须是矩形、且长和宽均为整数。切蛋糕时,每次切一块蛋糕,将其分成两个矩形蛋糕。请计算:最后得到的m块小蛋糕中,最大的那块蛋糕的面积下限。
假设w= 4, h= 4, m= 4,则下面的切法可使得其中最大蛋糕块的面积最小。
假设w= 4, h= 4, m= 3,则下面的切法会使得其中最大蛋糕块的面积最小:
4 4 4
4 4 3
0 0 0
4
6
/** 一看就是按递归的思想转换成动规 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,可是实现起来有点复杂,我也没有彻底搞明白,欢迎推荐更详细,更易懂的题解,感激不尽!
标签:面积 htm 测试 0ms 分享 pen 技术分享 最小值 log
原文地址:http://www.cnblogs.com/LuRenJiang/p/7402469.html