题目描述 给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]*k[1]*…*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
2 <= n <= 58
链接:https://leetcode-cn.com/problems/jian-sheng-zi-lcof
题解 总觉得像道数学题……动态规划求解。
初始状态:dp[2]=1,dp[i]在前面的基础上(dp[j], j=2,…,i-1)选择剪(dp[j]*(i-j))或不剪((i-j)*j)
dp[i]=max((i-j)*j, dp[j]*(i-j), j=2,…,i-1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 int cuttingRope (int n) { int * dp=new int [n+1 ]; for (int i=0 ;i<n;i++) dp[i]=0 ; dp[2 ]=1 ; for (int i=3 ;i<=n;i++) { for (int j=1 ;j<i;j++) { dp[i]=max(dp[i],(i-j)*max(j,dp[j])); } } return dp[n]; }
题目描述 和上面一样,只不过2 <= n <= 1000,答案需要取模 1e9+7(1000000007)
题解 或者,就直接用别人推导出的公式吧……切分规则:
最优: 3 。把绳子尽可能切为多个长度为 3 的片段,留下的最后一段绳子的长度可能为 0,1,2三种情况。
次优: 2 。若最后一段绳子长度为 2 ;则保留,不再拆为 1+1 。
最差: 1 。若最后一段绳子长度为 1 ;则应把一份 3 + 1 替换为 2 + 2,因为 2*2 > 3*1。
链接:https://leetcode-cn.com/problems/jian-sheng-zi-ii-lcof/solution/mian-shi-ti-14-ii-jian-sheng-zi-iitan-xin-er-fen-f/
但是会遇到溢出的问题……改用long long int的话就可以。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 int cuttingRope (int n) { if (n<4 )return n-1 ; int count=n/3 ; int left=n%3 ; long long int res=1 ; if (left==1 ) { count--; for (int i=0 ;i<count;i++) { res=(res*3 )%1000000007 ; } res=(res*4 )%1000000007 ; } else if (left==2 ) { for (int i=0 ;i<count;i++) { res=(res*3 )%1000000007 ; } res=(res*2 )%1000000007 ; } else { for (int i=0 ;i<count;i++) { res=(res*3 )%1000000007 ; } } return res; }