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

问题描述:

有一块矩形大蛋糕,宽和高分别是整数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,比较取较小值即可。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这本书是一本关于Python编程和算法基础的教程,适合初学者学习。书中内容涵盖了Python的基本语法、数据类型、控制结构、函数、面向对象编程、文件操作等基础知识,同时也介绍了常用的算法和数据结构,如排序、查找、栈、队列、链表等。此外,书中还提供了大量的练习和实例,帮助读者巩固所学知识。总之,这是一本很好的Python编程和算法入门教材。 ### 回答2: 《Python程序设计算法基础教程(第版)》是一本全面而深入的Python编程教材,它以系统化的方式介绍了Python编程语言的基本概念和算法基础知识,适合初学Python编程的读者和有经验的Python开发者。 本书为两部:第一部介绍了Python的基本概念,包括Python的数据类型、运算符、控制结构、函数、模块、文件和异常处理等,同时介绍了Python常用的数据结构,如列表、元组、字典和集合等,还介绍了Python的面向对象编程和异常处理机制。第介绍了Python中常用的算法和数据结构,包括排序算法、递归算法、图算法、树算法、动态规划和贪心算法等。通过学习这些算法,读者可以更加深入地了解Python编程语言的内部实现和运行原理。 本书的特点之一是使用了大量的实例和练习,通过实践,读者可以逐步熟悉Python的语法和算法基础知识,还可以学习Python应用领域中的实际问解决方法。 在这本书的编写过程中,作者注重了编程思想的培养,通过讲授Python的语言和算法,同时培养学生析问、思考解决方案,以及设计和实现解决方案的能力。因此,本书不仅适用于学生和初学Python编程的人群,还对那些想提高自己算法程序设计能力的Python开发者具有很强的实用性。 总之,《Python程序设计算法基础教程(第版)》是一本深入浅出、内容丰富、逻辑严谨的Python编程教材,可以帮助读者深入理解Python编程语言和算法基础知识,而且通过大量实际案例和练习,读者可以提高自己的Python编程能力和算法设计能力。 ### 回答3: 《Python程序设计算法基础教程(第版)》是一本针对初学者所编写的入门级Python编程教材,作者为姜红军。本书主要以Python 3版本为基础,提供了大量的例子,有助于读者深入理解编程概念和算法基础。本书的章节安排合理,内容全面,通俗易懂,是入门级别Python编程教材中的良心之作。 本书的第一部主要是 Python 基础语法的介绍。在学习Python编程的过程中,理解基础语法是一个重要的环节。因此,在本书中,作者对Python语法做了详细的介绍,包括变量、数据类型、字符串、函数、模块、文件IO等等。每个知识点都提供了足够多的例子和练习,帮助读者理解并掌握Python语法。 第为Python编程的常用数据结构和算法。学习编程,需要有一定的算法基础,而本书在这方面也有极为全面的介绍。这一部主要介绍了Python中的列表、元组、字典、集合等数据结构,同时介绍了常用的算法,包括线性查找、查找、递归算法、排序、叉树等等。本书的例子和习涵盖了各种数据结构和算法的应用场景,可以帮助读者有效地掌握这些内容。 第三部为Python编程的高级应用。当读者基本掌握Python语法和数据结构后,需要学习更高级的编程应用才能更好地使用Python。这一部主要讲解了Python的网络编程、并发编程、GUI编程、数据库编程等高级应用。本书中有着丰富的例子和练习,读者可以学习这些高级应用并运用到实际开发中。 总之,本书是一本很好的Python编程入门教材,适合有编程基础的人士阅读。无论是对于编程初学者还是有编程经验的开发者,本书都是很好的Python语言学习资料。希望更多的Python初学者可以通过本书学习到Python编程知识,进而能够在Python开发领域中获得更大的进展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值