程序设计与算法(二)算法基础7.5分蛋糕

本文探讨了一种动态规划方法解决切蛋糕问题,通过最少切割次数将大蛋糕分成m块,目标是找到最大蛋糕块的面积下限。涉及边界条件判断、两种切割策略(横纵)对比及递归计算最小面积。适合解决最值优化的蛋糕切分问题。
摘要由CSDN通过智能技术生成

问题描述:

有一块矩形大蛋糕,宽和高分别是整数w、h。 现要将其切成m块小蛋糕,每个小蛋糕都必须是矩形,且宽和高均为整数。切蛋糕时,每次切一块蛋糕,将其分成两个矩形蛋糕。请计算:最后得到的n块小蛋糕中,最大的那块蛋糕的面积下限。

例如:

假设w= 4, h= 4, m= 4,则下面的切法可使得其中最大蛋糕块的面积最小(m=4则切三刀,分别书1.竖刀,2.左横刀,3.右横刀);


 

 假设w= 4, h= 4, m= 3,则下面的切法可使得其中最大蛋糕块的面积最小(m=3则切两刀,1.竖刀,2.横刀)。

 输入

共有多行,每行表示一个测试案例。每行是三个用空格分开的整数W, H, M,其中1≤W,H,M≤20,M≤W*H。当W=H=M=0时不需要处理,表示输入结束。

输出

每个测试案例的结果占一行, 输出一个整数,表示最大蛋糕块的面积下限。

思路:

1.较复杂的动态规划问题,是求最值一类的问题;

2.因为不会有交叉刀,所以每一刀都是由1块变为两块,因此需要切m-1刀。而且,蛋糕块数从1依次变到m,不会出现倍数增加,大大简化了问题;

//ways(w,h,m)=min(row,column);第一刀为横或竖,取这两种的最小值
//row=min(si);//以横刀为例,如果是横刀,这一刀切在哪里影响着面积的大小,取最小值
//si=max(ways(w,i,j),ways(w,h-i,m-j))当这一刀位置确定,切在h为i处,那么把蛋糕分为了两部分
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int num[20][3];
int ways(int w,int h,int m)
{
	if(w*h<m)return 400;//边界条件
	if(m==1)return w*h;
	int r[h],c[w];//分别代表row向和column向
	for(int i=1;i<h;i++){
		r[i]=400;
		for(int j=1;j<m;j++){
			int rowmin=max(ways(w,i,j),ways(w,h-i,m-j));
			if(rowmin<r[i])r[i]=rowmin;
		}
	}
	for(int i=1;i<w;i++){
		c[i]=400;
		for(int j=1;j<m;j++){
			int columnmin=max(ways(i,h,j),ways(w-i,h,m-j));
			if(columnmin<c[i])c[i]=columnmin;
		}
	}
	int row=*min_element(r+1,r+h);
	int column=*min_element(c+1,c+w);
	return min(row,column);
}
int main()
{
	int n=1;
	for(int i=0;i<20;i++){
		cin>>num[i][0]>>num[i][1]>>num[i][2];
		if(num[i][0]==0)break;
		n++;
	}
	for(int i=0;i<n;i++){
		cout<<ways(num[i][0],num[i][1],num[i][2])<<endl;
	}
}

3.以函数ways(w,h,m)表示w*h大的蛋糕切成m块最小的最大面积,边界条件有两个:首先,w*h要大于等于m,m块蛋糕面积最小为m,如果w*h还要小说明方法错误,返回20*20即可;其次,当m=1时,无法再切了,返回w*h即可;

4.首先看第一刀,有两种选择:横刀或者竖刀。这属于两类,需要取这两类的较小值;

5.以横刀为例,这一刀切在哪里影响着面积的大小,所以需要遍历1到h-1,找出其中的最小值;

6.当第一刀的位置确定,切在h=i处时,蛋糕被分为两部分,一部分为(w,i),另一部分为(w,h-i),这两部分一共会被分为m块,但是每一块被分成的块数也会影响面积大小,如果一个被分为j块,另一个则被分为m-j块,j的大小也会影响面积。所以要从1到m-1遍历j,遍历的时候比较ways(w,i,j)和ways(w,h-i,m-j),取最大值(原因详见“7”),然后取m-1个最大值中的最小值;

7.因为ways(w,i,j)和ways(w,h-i,m-j)是同时出现的,如果取前者,若后者出现更大的面积,那么也只能妥协取后者较大的面积,因为你要求的就是每一种情况下的最大面积,这种情况下的最大面积才是结果。

8。双循环,外层循环i代表第一刀的位置,当i确定后,内层循环循环两侧的块数j;先从两个ways中取最大值,内层共有m-1个最大值,在其中选择最小值,这个最小值一共有h-1个,即外层循环,再从这最小值中选择最小值,作为row,同样的方法求出column,比较取较小值即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值