题目:给你一根长度为n的绳子,请把绳子剪成m段(m,n都是整数,n > 1 并且m > 1),每段绳子的长度记为k[0], k[1], ...k[m]。请问k[0] x k[1] x ... x k[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

测试用例:

  • 功能测试(绳子的初始长度大于5)。
  • 边界值测试(绳子的初始长度分别为0、1、2、3、4)。

测试代码:

void test(const char* testName, int length, int expected)
{
int result1 = maxProductAfterCutting_solution1(length);
if(result1 == expected)
std::cout << "Solution1 for " << testName << " passed." << std::endl;
else
std::cout << "Solution1 for " << testName << " FAILED." << std::endl; int result2 = maxProductAfterCutting_solution2(length);
if(result2 == expected)
std::cout << "Solution2 for " << testName << " passed." << std::endl;
else
std::cout << "Solution2 for " << testName << " FAILED." << std::endl;
}
void test1()
{
int length = 1;
int expected = 0;
test("test1", length, expected);
}
void test2()
{
int length = 2;
int expected = 1;
test("test2", length, expected);
}
void test3()
{
int length = 3;
int expected = 2;
test("test3", length, expected);
}
void test4()
{
int length = 4;
int expected = 4;
test("test4", length, expected);
}
void test5()
{
int length = 5;
int expected = 6;
test("test5", length, expected);
}
void test6()
{
int length = 6;
int expected = 9;
test("test6", length, expected);
}
void test7()
{
int length = 7;
int expected = 12;
test("test7", length, expected);
}
void test8()
{
int length = 8;
int expected = 18;
test("test8", length, expected);
}
void test9()
{
int length = 9;
int expected = 27;
test("test9", length, expected);
}
void test10()
{
int length = 10;
int expected = 36;
test("test10", length, expected);
}
void test11()
{
int length = 50;
int expected = 86093442;
test("test11", length, expected);
}

本题考点:

  • 考查应聘者的抽象建模能力。应聘者需要把一个具体的场景抽象成一个能够用动态规划或者贪婪算法解决的模型。
  • 考查应聘者对动态规划和贪婪算法的理解。能够灵活运用动态规划解决问题的关键是具备从上到下分析问题、从下到上解决问题的能力,而灵活运用贪婪算法则需要扎实的数学基本功。

动态规划:

int maxProductAfterCutting_solution1(int length)
{
if(length < 2)
return 0;
if(length == 2)
return 1;
if(length == 3)
return 2;
int* products = new int[length + 1];
products[0] = 0;
products[1] = 1;
products[2] = 2;
products[3] = 3;
int max = 0;
for(int i = 4; i <= length; ++i)
{
max = 0;
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;
}

贪婪算法:

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;
int timesOf2 = (length - timesOf3 * 3) / 2;
return (int) (pow(3, timesOf3)) * (int) (pow(2, timesOf2));
}

剑指offer笔记面试题14----剪绳子的更多相关文章

  1. 【剑指offer】面试题 14. 剪绳子

    面试题 14. 剪绳子 LeetCode 题目描述 给你一根长度为 n 的绳子,请把绳子剪成 m 段(m.n 都是整数,n>1 并且 m>1),每段绳子的长度记为 k[0],k[1],·· ...

  2. 《剑指offer》面试题14- I. 剪绳子

    问题描述 给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m.n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m] .请问 k[0]*k[1]* ...

  3. 《剑指offer》面试题14- II. 剪绳子 II

    问题描述 给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m.n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m] .请问 k[0]*k[1]* ...

  4. (剑指Offer)面试题14:调整数组顺序使奇数位于偶数前面

    题目: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 如果去掉约束条件: ...

  5. 剑指offer笔记面试题2----实现Singleton模式

    题目:设计一个类,我们只能生成该类的一个实例. 解法一:单线程解法 //缺点:多线程情况下,每个线程可能创建出不同的的Singleton实例 #include <iostream> usi ...

  6. 剑指offer笔记面试题1----赋值运算符函数

    题目:如下为类型CMyString的声明,请为该类型添加赋值运算符函数. class CMyString{ public: CMyString(char* pData = nullptr); CMyS ...

  7. 剑指offer笔记面试题3----数组中重复的数字

    题目一:找出数组中重复的数字.在一个长度为n的数组里的所有数字都在0~n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数字.例如 ...

  8. 剑指offer笔记面试题4----二维数组中的查找

    题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 测试用例: 二维数组中包含 ...

  9. 剑指offer笔记面试题5----替换空格

    题目:请实现一个函数,把字符串中的每个空格替换成"20%".例如,输入"We are happy."则输出"We%20are%20happy.&quo ...

随机推荐

  1. 在Chrome 中使用Vimium

    原文连接:https://blog.csdn.net/wuxianjiezh/article/details/91848604 Vimium:像在 Vim 中一样使用 Chrome 安装 使用方法 在 ...

  2. Java用广度优先搜索快速搜索文件

    背景 在开发的过程中,经常需要在文件系统里按某些条件搜索文件,比如音乐播放器扫描音乐,而搜索文件,大多人喜欢用递归的方式,而这也是最容易想到的方式.递归方式如果文件夹很深就容易造成栈溢出,而且不断的压 ...

  3. Context知识详解

    Context知识详解 建议配合context知识架构图食用. 一.什么是Context 贴一个官方解释: Interface to global information about an appli ...

  4. Hive初步认识,理解Hive(一)

    Hive初步认识,理解Hive(一) 用了有一段时间的Hive了,之前一直以为hive是个数据库,类似Mysql.Oracle等数据库一样,其实不然. Hive是实现Hadoop 的MapReduce ...

  5. Java编程思想——第17章 容器深入研究(一)

    这一章将学习散列机制是如何工作的,以及在使用散列容器时怎么样编写hashCode()和equals()方法. 一.容器分类 先上两张图 来概况完整的容器分类 再细说都为什么会有那些特性. 二.Coll ...

  6. springboot(二):bootstrap和application有什么区别?

    “SpringBoot专注于快速方便的开发单个个体微服务. SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来, 为各个服务之间提供 ...

  7. 如何利用随机数产生验证码(java基础知识)

    以前我们通用的验证码都是五个不同的大小写字母,那么今天我就带大家学习一下利用Java基础怎么生成验证码.首先我们应该有一个清晰的思路:首先定义一个固定长度的数组用来存储需要生成的字母:其次生成随机数, ...

  8. ribbon客户端负载均衡

    Ribbon简介 参考:https://blog.csdn.net/chengqiuming/article/details/80711168 Ribbon是Netflix发布的负载均衡器,它有助于控 ...

  9. 43.QT-访问远程SQLite数据库

    在上章42.QT-QSqlQuery类操作SQLite数据库(创建.查询.删除.修改)详解学习了如何操作SQLite,本章来学习如何访问远程SQLite 1.首先设置共享,映射(用来实现远程访问) 将 ...

  10. JDK8,Optional

     作为程序员,你肯定遇到过NullPointerException, 这个异常对于初出茅庐的新人, 还是久经江湖的老手都是不可避免的痛, 可又是那么的无能为力,为了解决它,你只能在使用某个值之前,对其 ...