数据结构 贪心算法 动态规划 学习笔记

首先我们了解一下贪心算法  

举例 :一根绳子  长度为8  怎么剪  每段绳子的乘积最大?

这里我们找规律  只有剪成n个长度为三的绳子 乘积最大  但是 这样剪会遇到以下几种情况

1.剩了一段长度为1的绳子

如果遇到这种情况 我们就少剪出一段长度为3的绳子  用这一段和剩下的长度为1的绳子拼一下 得到长度为4 的绳子  再将它剪成2段长度为2 的绳子

2.剩了一段长度为2的绳子

假设减了n个长度为3的绳子  剩了一段长度为2的绳子 

乘积=3*n*2;

3.没剩

乘积=3*n;

具体代码如下

int cNum(int Num)
{
	//排除小于等于3的情况
	if (Num < 2)
		return 0;
	if (Num == 2)
		return 2;
	if (Num == 3)
		return 3;
	//绳子大于3  nCountof3记录段数
	int nCountof3 = Num / 3;
	if (Num - nCountof3 == 1)//余下的绳子长度=1  少剪一段长度为3的  用于和长度为1的拼
		nCountof3--;
	
	//判断剩了的绳子可以剪成几段长度为2的绳子
		int nCountof2 =(Num - nCountof3 *3)/ 2;

	return (int)pow(3, nCountof3) *(int)pow(2, nCountof2);//乘积=3的(nCountof3)次方*2的(nCountof2)次方  
}

接下来  了解一下动态规划 

动态分配一般当前的问题会与之前处理的两个问题有关联

  如:

斐波那契数列 f(n)=f(n-1)+f(n-2);

一般我们采用动态分配的方法时  都会生成这样一种解决方案的函数  

在这道题中 我们的思路是

开辟一个数组  

当前元素等于   下标相加等于当前元素的下标  的两个元素的乘积的最大值   

如当前元素为4     1,3     2,2  符合    那么看   pArr[1]*pArr[3]   和  pArr[2]*pArr[2] 谁大  大的乘积为pArr[4]的值

代码如下

int DP(int Num)
{
	if (Num < 2)
		return 0;
	if (Num == 2)
		return 2;
	if (Num == 3)
		return 3;
	int* pArr = new int[Num + 1];
	::memset(pArr, 0, sizeof(int) * (Num + 1));
	pArr[0] = 0;
	pArr[1] = 1;
	pArr[2] = 2;
	pArr[3] = 3;
	int Sum = 0;
	for (int i = 4; i <= Num; i++)
	{
		int max = 0;
		for (int j = 0; j < i / 2; j++)
		{
			if (pArr[j+1] * pArr[i - j - 1] > max)
			{
				max=pArr[j+1] * pArr[i - j - 1];
				
			}
		}
		pArr[i] = max;
		Sum = max;
	}
	delete []pArr;
	pArr = NULL;
	return Sum;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值