剪绳子

  解决这个问题,我们有两种办法:(1)动态规划(2)贪婪算法。

      动态规划: 时间复杂度为O(n^2)空间复杂度O(n)

      贪婪算法:时间复杂度为O(1)空间复杂度O(1)

1.动态规划

      当绳子长度为1和0时,不能被剪;

      当绳子长度为2时,只能剪成1和1,所以f(2)=1;

      当绳子长度为3时,只能剪成1和3,所以f(3)=2;

      我们先得到f(2)和f(3)的值,在得到f(4)和f(5)的值,依次..........直到得到f(n)的值。

2.贪婪算法

      当绳子长度>=5时,我们尽可能多的剪长度为3的绳子,当剩下的绳子为4时,我们把绳子剪成两段长度为2的绳子。

参考代码:

int Smax(int ropelength)//动态规划
{
	int* tmp = NULL;
	int max = 0;
	int i, j;
	tmp = (int*)malloc((sizeof(int))*(ropelength + 1));
	tmp[0] = 0;
	tmp[1] = 1;
	tmp[2] = 2;
	tmp[3] = 3;
	if (ropelength < 2)
		return 0;
	if (ropelength == 2)
		return 1;
	if (ropelength == 3)
		return 2;
	for (i = 4; i <= ropelength; i++)
	{
		for (j = 1; j <= i / 2; j++)
		{
			int product = tmp[j] * tmp[i - j];
			if (product>max)
				max = product;//更新最大乘积
		}
		tmp[i] = max;
	}
	max = tmp[ropelength];
	free(tmp);	
        tmp = NULL;
	return max;
}
int Smax1(int ropelength)//贪婪算法
{
	int x, y;
	int i,power=3;
	if (ropelength < 2)
		return 0;
	if (ropelength == 2)
		return 1;
	if (ropelength == 3)
		return 2;
	if (ropelength == 4)
		return 2 * 2;
	if (ropelength >= 5)
	{
		x = ropelength / 3;
		y = ropelength % 3;
	}
	for (i = 0; i < x - 1; i++)
		power *=3;//3的x次方
	if (y == 0)
		return power;//整除的话,返回3的x次方
	else if (y == 1)
		return (power / 3) * 2 * 2;//y=1时,相当于绳子有一段时间,剩余长度为4,剪成2*2
	else
		return power*y;
}
int main()//剪绳子
{
	int ropelength = 5;
	int ret = Smax(ropelength);
	int ret1 = Smax1(ropelength);
	printf("面积最大是:%d(动态规划)\n", ret);
	printf("面积最大是:%d(贪婪算法)\n", ret1);
	system("pause");
	return 0;
}

   

猜你喜欢

转载自blog.csdn.net/oldwang1999/article/details/82875329
今日推荐