【C/C++练习题】剪绳子

举报
王建峰 发表于 2021/11/19 00:04:32 2021/11/19
【摘要】 《剑指Offer》面试题14:剪绳子 1 题目 给你一根长度为n绳子,请把绳子剪成m段(m、n都是整数,n>1并且m≥1)。每段的绳子的长度记为k[0]、k[1]、……、k[m]。k[0]*k[1]*…*k[m]可能的最大乘积是多少?例如当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到最大的乘积18。 ...

《剑指Offer》面试题14:剪绳子


1 题目

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

 

2 算法分析&问题分析

动态规划:适用于求问题的最优解。首先从上向下分析问题,要将一个大问题划分成两个子问题,遍历每一种方案并确定当前最优解,分别对子问题进一步划分求最优解,直到最小问题的最优解求出。将小问题的最优解回归,解出问题的最优解。

由于自上而下的递推公式会产生多个重复的子问题。因此选用自下而上迭代的方法,从已知条件求出最优解。

要使用一个数组来记录每一个子问题的最优解。

  1. 绳长 n > 3,利用迭代方式进行动态规划

 

贪心算法:基于一个计算策略(有数学方法证明),每一步都是一个贪婪的选择。

  1. 绳长 n >= 5 剪长度为3的绳子
  2. 绳长 n == 4 剪成两段长度为2的绳子

 

3 代码分析


  
  1. #include "iostream"
  2. #include <cstring>
  3. using namespace std;
  4. //动态规划求解
  5. //输入:绳子的长度 length
  6. //返回:最优解
  7. int max_to_cut(int length)
  8. {
  9. //1.考虑特殊情况下的最优解
  10. if (length < 2) return 0;
  11. if (length == 2) return 1;
  12. if (length == 3) return 3;
  13. int* products = new int [length + 1]; //用于纪录所有子问题的最优解
  14. //2.设置已知小问题的最优解
  15. products[1] = 1;
  16. products[2] = 2;
  17. products[3] = 3;
  18. //3.迭代法进行动态规划
  19. for (int i = 4;i <= length;i++)
  20. {
  21. int max = i;
  22. //遍历每一种可行的切割方案,选出最优
  23. for (int j = 1;j <= i/2; j++)
  24. {
  25. int product = products[j] * products[i-j];
  26. if (max < product)
  27. {
  28. max = product;
  29. }
  30. }
  31. //记录该问题的最优解
  32. products[i] = max;
  33. }
  34. delete [] products;
  35. //4.返回最优解
  36. return products[length];
  37. }
  38. //贪婪算法求解
  39. //输入:绳子的长度 length
  40. //返回:最优解
  41. int new_max_to_cut(int length)
  42. {
  43. //1.考虑特殊情况下的最优解
  44. if (length < 2) return 0;
  45. if (length == 2) return 1;
  46. if (length == 3) return 3;
  47. //2.尽可能剪长度为3的绳子
  48. int n_length3 = length/3;
  49. //3.剩下长度为4的时候,不必要在剪断了
  50. if (length % 3 == 1)
  51. {
  52. n_length3 -= 1;
  53. return (pow(3, n_length3) * pow(2, 2)); //返回最优解,长度为4的部分剪短成2+2
  54. }
  55. //4.通常情况下,返回的最优解
  56. int n_length2 = length - n_length3*3;
  57. return (pow(3, n_length3) * n_length2);
  58. }
  59. int main(int argc, char const *argv[])
  60. {
  61. int n;
  62. cin >> n;
  63. // cout << endl;
  64. cout << max_to_cut(n) << endl;
  65. cout << new_max_to_cut(n) << endl;
  66. return 0;
  67. }

 

4 运行结果

文章来源: blog.csdn.net,作者:hinzer,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/feit2417/article/details/98431603

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。