动态规划之二:剪绳子问题

原创 2018年04月15日 20:58:56

问题:现有一根长度为N的绳子,需要你剪成M段,使M段的乘积最大。(其中M、N都为整数,剪成的每段长度也为整数,N已知,M未知)

例如 绳子长度N=8 剪成M=3,数值为别为2,3,3,则乘积最大为 2*3*3=18。

 当我们遇到一个大规模问题时,总是习惯把问题的规模变小,这样便于分析讨论。

我们从最简单的情况进行分析:

当绳子的长度N=1时,我们至少需要剪绳子一次,这时乘积为0;

当绳子的长度为N=2时,剪一次后绳子的两段长度为分别为1、1,这时乘积为1*1=1;

当绳子的长度为N=3时,我们对绳子有两种方式,其一为剪成三段,它们的长度分别为1、1、1,乘积为1*1*1=1;其二为剪成两段,它们的长度分别为1、2,乘积为1*2=2,则最终乘积取这两种方式中的最大值为max(1*1*1,1*2)。

当绳子的长度为N=4时,我们对绳子有三种方式,其一为剪成四段,它们的长度分别为1、1、1、1.乘积为1*1*1*1=1;其二为剪成两段,他们的长度为1、3.乘积为1*3=3,其三为剪成三段,它们的长度分别为1、2、1,乘积为1*2*1=2;其四为剪成两段,它们的长度分别为2、2,乘积为2*2=4;则最终乘积取上面结果中最大值max(1*1*1*1,1*3,1*2*1, 1*2)。

现在我们要用数学符号表示剪绳子的最大乘积的状态,使用f(N)表示绳子长度为N剪成若干段的最大乘积状态,由上面分析可知,

当N=1时,f(1)=0;

当N=2时,f(2)=1*1=1;

当N=3时,f(3)=max(1*1*1,1*2)=2

当N=4时,f(4)=max(1*1*1*1,1*3,1*2*1, 1*2)=4

我们知道使用动态规划求解问题,需要具备其中一个性质:最优子结构性质,也即我们需要知道状态转移函数。通过对上述状态的描述我们可以进一步简化中间环节:

当N=1时,f(1)=0;

当N=2时,f(2)=1;

当N=3时,f(3)=f(1)*f(2)=2

当N=4时,f(4)=max(f(1)*f(3),f(2)*f(2))=4

当N=5时,f(5)=max(f(1)*f(4),f(2)*f(3))=6

   .......

                f(N)=max(f(1)*f(N-1), f(2)*f(N-2) , f(3)*f(N-3) , ... , f(i)*f(N-i) )

由此,我们可以知道状态转移函数为:f(N)= max( f(i) * f(N-i)  ) , 其中i的取值范围为(i>0&&i<=n/2)。


程序如下所示:

#include<iostream>
using namespace std;
#define size 100  //表格的大小

int Line_Max(int a[],int n) {
	if (n < 2)
		return 0;
	if (n == 2)
		return 1;
	if (n == 3)
		return 2;
	for (int i = 4; i <= n; i++) 
		for(int j=1;j<=i/2;j++)     //比较的范围为:(1,n/2)
			if (a[j]*a[i-j]>a[i]) 
				a[i] = a[j] * a[i - j];
	return a[n];
}

int main() {
	int table[size]= { 0,1,2,3 };//对表格进行初始化,用来存储长度为i的最大乘积值
	int n;
	cin >> n;
	cout << Line_Max(table, n) << endl;
	
}




剑指Offer(第二版)面试题14:剪绳子(动态规划)

剑指Offer(第二版)面试题14:剪绳子(动态规划)
  • qq_25827845
  • qq_25827845
  • 2017-06-16 21:45:00
  • 4628

剑指offer--面试题14:剪绳子

#include #include // ====================动态规划==================== int maxProductAfterCutting_solut...
  • u010726692
  • u010726692
  • 2017-07-12 10:32:50
  • 888

动态规划之割绳子

题目:给你一根长度为n的绳子,请把绳子剪成m段 (m和n都是整数,n&amp;gt;1并且m&amp;gt;1)每段绳子的长度记为k[0],k[1],…,k[m]. 请问k[0]k[1]…*k[m]可...
  • qq_27139155
  • qq_27139155
  • 2018-03-28 10:27:15
  • 103

动态规划之二:剪绳子问题

问题:现有一根长度为N的绳子,需要你剪成M段,使M段的乘积最大。(其中M、N都为整数,剪成的每段长度也为整数,N已知,M未知)例如 绳子长度N=8 剪成M=3,数值为别为2,3,3,则乘积最大为 2*...
  • zjx_cfbx
  • zjx_cfbx
  • 2018-04-15 20:58:56
  • 140

动态规划or贪心算法--剪绳子/切割杆

需求一: 剪绳子,将长度为n的绳子剪成若干段,求各段长度乘积的最大值分析: 1、动态规划    设f(n)代表长度为n的绳子剪成若干段的最大乘积,如果第一刀下去,第一段长度是i,那么剩下的就需要剪n-...
  • upupday19
  • upupday19
  • 2018-02-12 12:06:41
  • 339

动态规划 割绳子

public class Offer14 { static int maxProduct(int n) { if(n&amp;lt;2) { return 0; } if(n...
  • qq_39147516
  • qq_39147516
  • 2018-03-09 17:59:20
  • 104

搜索-O - 切绳子问题(二分)

//题意:有n条绳子,分成k段相等的,问能使得最长为多长 思路:经典二分 输入n 段绳子的完了之后,计算 k段平均长度,在0-sum/k, 之间二分,如果分的绳子多余k 段的话,说明绳子太短了,需要...
  • Joined
  • Joined
  • 2017-05-25 08:50:09
  • 619

《面试--动态规划》 ---五种经典的算法问题

一 动态规划 动态规划问题是面试题中的热门话题,如果要求一个问题的最优解(通常是最大值或者最小值),而且该问题能够分解成若干个子问题,并且小问题之间也存在重叠的子问题,则考虑采用动态规划。 使用动...
  • tongxinzhazha
  • tongxinzhazha
  • 2017-08-19 11:02:49
  • 3541

动态规划经典问题--TSP问题

Travelling Salesman Problem 旅行商问题,即TSP问题(Travelling Salesman Problem)又译为旅行推销员问题、货郎担问题,是数学领域中著名问题...
  • hu413031273
  • hu413031273
  • 2016-05-06 10:30:49
  • 8440
收藏助手
不良信息举报
您举报文章:动态规划之二:剪绳子问题
举报原因:
原因补充:

(最多只允许输入30个字)