面试题14:剪绳子(动态规划,贪心算法)

news/2024/7/7 10:01:37

一、题目:

一根长度为n的绳子,剪成m段,m,n都大于1,且都为整数,每段长度记为k[0],k[1]…,k[m].求k[0]*k[1]…*k[m]可能的最大乘积

1.1解法:

两种不同的方法解决这个问题,先用常规的需要O(n²)时间和O(n)空间的动态规划,接着用只需要O(1)的时间和空间的贪心算法。

二、动态规划:

(1)是求最优解问题,如最大值,最小值;
(2)该问题能够分解成若干个子问题,并且子问题之间有重叠的更小子问题。

2.1通常按照如下4个步骤来设计一个动态规划算法:

(1)刻画一个最优解的结构特征;
(2)递归地定义最优解的值;
(3)计算最优解的值,通常采用自底向上的方法;
(4)利用计算出的信息构造一个最优解。

2.2用动态规划分析问题

首先定义函数f(n)为把长度为n的绳子剪成若干段后各段长度乘积的最大值。在剪第一刀的时候,我们有n-1中可能的选择,也就是剪出来的第一段绳子可能长度为1,2,…,n-1。因此f(n) = max(f(i) * f(n-i))。其中0<i<n。

2.3代码实现:

int maxProductAfterCutting_Solution(int length)
{
	//绳子在3米以内,直接返回对应的值,不能用动态规划的公式做
	if(length<2)
		return 0;
	if(length==2)
		return 1;
	if(length==3)
		return 2;
	//创建数组存储子问题最优解
	int* products=new int[length+1];//?
	//绳子大于3米,可以用动态规划的公式做,f(n)=f(i)*f(n-i)
	//对于绳子长度为1,2,3米的,绳子的最大乘积就是长度本身
	products[0]=0;
	products[1]=1;
	products[2]=2;
	products[3]=3;

	int max=0;
	//从4米开始计算,直到计算到总长
	for(int i=4;i<=length;++i)
	{
		max=0;
		//对于长度为i的绳子,计算所有可能的切分,找到最大值
		for(int j=1;j<=i/2;++j)
		{
			//切分组合
			int product=products[j]*products[i-j];
			if(max<product)
				max=product;

			products[i]=max;
		}
	}
	max=products[length];
	delete[] products;

	return max;
}

三、贪心算法:

在每一步求解的步骤中,他要求每一步都是最优选择操作,并且通过一系列的最优选择,能够产生一个问题的(全局的)最优解

3.1 贪心算法满足的条件

1、可行的:即它必须满足问题的约束
2、局部最优:他是当前步骤中所有可行选择中最佳的局部选择
3、不可取消:即选择一旦选出,在算法的后面步骤就不可更改了

3.2 用贪心算法分析问题

如果我们按照如下的策略来剪绳子,则得到的各段绳子的长度的乘积将最大:当n≥5时,我们尽可能多的剪长度为3的绳子:当剩下的绳子长度为4时,把绳子剪成两段长度为2的绳子。

3.3代码实现:

int maxProductAfterCutting_Solution2(int length)
{
	if(length<2)
		return 0;
	if(length==2)
		return 1;
	if(length==3)
		return 2;

	//尽可能的减去长度为3的绳子段
	int timesOf3=length/3;
	//当绳子最后剩下的长度为4的时候,不能再减去长度为3的绳子段
	//此时更好的方法是把绳子剪成长度为2的两段,因为2*2>3*1
	if(length-timesOf3*3==1)
		timesOf3-=1;
	
	//最后小于等于4米的,尽量多的产生2米的分割
	int timesOf2=(length-timesOf3*3)/2;

	//3的多少个三次幂乘以2的多少个2次幂
	return (int)(pow(3.0,timesOf3))*(int)(pow(2.0,timesOf2));
}

四、测试及结果

4.1 测试代码

int main()
{
	printf("%d\n",maxProductAfterCutting_Solution(10));
	printf("%d\n",maxProductAfterCutting_Solution2(10));
	return 0;
}

4.2 测试结果

在这里插入图片描述


http://www.niftyadmin.cn/n/4058282.html

相关文章

python re模块导入_Python正则re模块使用步骤及原理解析

python中使用正则表达式的步骤&#xff1a;1.导入re模块&#xff1a;import re2.初始化一个Regex对象&#xff1a;re.compile()3.刚刚创建的Regex对象调用search方法进行匹配&#xff0c;返回要给March对象4.刚刚的March对象调用group方法&#xff0c;展示匹配到的字符串下面例…

面试题4:二维数组的查找

一、题目 在一个二维数组中&#xff0c;每一行都按照从左到右递增的顺序排序。每一列都按照从上到下递增的顺序排序&#xff0c;请完成一个函数&#xff0c;输入这样的一个二维数组和一个整数&#xff0c;判断数组是否含有该整数。 二、算法分析 一个从左到右&#xff0c;从…

6脉冲触发器脉冲缺失_脉冲袋式除尘器6个主要构件特点及5个常见问题及处理措施...

随着国家环保要求越来越高&#xff0c;对大气粉尘污染的严格管控&#xff0c;除尘设备在多领域得到大量应用&#xff0c;在防治粉尘污染、改善作业环境、实现烟气达标排放方面发挥着很大作用。本文分享脉冲袋式除尘器6个主要构件特点及5个常见问题及处理措施。1.脉冲袋式除尘器…

快速排序及五种优化(模板)

1、快速排序的基本思想&#xff1a; 快速排序排序使用分治的思想&#xff0c;通过一趟排序将待排序列分割成两部分&#xff0c;其中一部分记录的关键字均比另一部分记录的关键字小。之后分别对这两部分记录继续进行排序&#xff0c;递归地以达到整个序列有序的目 2、快速排序…

SCAU 汇编语言 期末复习 (上)

第一章 1.储存单位 存储容量&#xff1a;bit 、Byte、 Word 1 kilobytes210bytes1024bytes 1megabyte(MB)220bytes 1gigabyte(GB)230bytes 1terabyte(TB)240bytes 1petabyte250bytes 1exabyte260bytes 1zettabyte270bytes 1yottabyte280bytes 2个字节&#xff1a; Word &#…

双光耦开关电源电路图_六款简单的开关电源电路设计原理图详解

简单的开关电源电路图(一) 简单实用的开关电源电路图调整C3和R5使振荡频率在30KHz-45KHz。输出电压需要稳压。输出电流可以达到500mA.有效功率8W、效率87%。其他没有要求就可以正常工作。简单的开关电源电路图(二)24V开关电源&#xff0c;是高频逆变开关电源中的一个种类。通过…

序列容器vector和迭代器

一、容器vector vector类模板提供了一种占用连续内存地址的数据结构。这使得它可以高效&#xff0c;直接的利用下标运算符[]访问vector中的任一元素&#xff0c;当一个vecto的内存空间耗尽时&#xff0c;它会分配一个更大的连续空间&#xff08;数组&#xff09;&#xff0c;把…

SCAU 软件工程 期末复习

软件发展阶段 程序设计阶段——50至60年代 程序系统阶段——60至70年代 软件工程阶段——70年代以后 软件工程的生命周期 1.需求分析&#xff08;RequirementsCapture&#xff09; 2.系统分析与设计&#xff08;SystemAnalysis and Design&#xff09; 3.系统实现&#…