解决这个问题,我们有两种办法:(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;
}