如果绳子长度为2,则最大乘积为1 x 1 = 1;如果绳子长度为3,则最大乘积为1 x 2 = 2。
如果使用动态规划,则dp[i]表示长度为i的绳子,剪断后能获得的最大乘积。
长度为i的绳子,其最大值应该是
m
a
x
(
d
p
[
1
]
∗
d
p
[
i
−
1
]
,
d
p
[
2
]
∗
d
p
[
i
−
2
]
,
.
.
.
,
d
p
[
i
−
1
]
∗
d
p
[
1
]
)
max(dp[1]*dp[i-1], dp[2]*dp[i-2], ... , dp[i-1]*dp[1])
max(dp[1]∗dp[i−1],dp[2]∗dp[i−2],...,dp[i−1]∗dp[1])。
可以发现:到了i/2后,后面的乘积就是重复的,只需要计算到i/2即可。
动态数组的初始化至关重要:
如果长度小于等于3,直接返回对其裁剪的结果:f(2)=1, f(3)=2。
否则,初始化动态数组时,表明长度为1, 2, 3的绳子都是子段,值应该为本身,而非上面的值。
动态规划的代码如下:
publicintintegerBreak(int n){// 不能将其作为子段的话,直接返回if(n==2){return1;}if(n==3){return2;}// 初始化动态数组,如果长度小于1直接返回nint[] dp =newint[n +1];
dp[1]=1;// 作为子段,不能再细分了
dp[2]=2;
dp[3]=3;for(int i =4; i <= n; i++){int max =0;for(int j =1; j <= i /2; j++){int temp = j * dp[i - j];if(max < temp){
max = temp;
dp[i]= temp;}}}return dp[n];}
② 贪心算法
贪心算法:每次都按照结果最大的情况进行取值。
如果绳子长度大于4,每次都先按照3进行裁剪。
直到绳子长度小于等于4,按照2进行裁剪。
这样,最后的每段绳子的乘积将会是最大的。
记录整个绳子被剪成长度为3和长度为2的次数,就可以知道整个绳子的最大乘积:
3
i
+
2
j
3^i+2^j
3i+2j
publicStringaddStrings(String num1,String num2){// 特殊情况,不用计算if(num1.length()==0){return num2;}if(num2.length()==0){return num1;}// 末位对齐,向高位依次进行加法计算int m = num1.length()-1, n = num2.length()-1;String result ="";int flag =0;while(m >=0&& n >=0){int a = num1.charAt(m--)-'0';int b = num2.charAt(n--)-'0';int sum = a + b + flag;// 加上进位
flag = sum /10;
sum = sum %10;
result = sum + result;}while(m >=0){//num1有剩余int a = num1.charAt(m--)-'0';int sum = a + flag;
flag = sum /10;
sum = sum %10;
result = sum + result;}while(n >=0){//num2有剩余int a = num2.charAt(n--)-'0';int sum = a + flag;
flag = sum /10;
sum = sum %10;
result = sum + result;}if(flag ==1){
result =1+ result;}return result;}
publicListNodeaddTwoNumbers(ListNode l1,ListNode l2){// 某一个链表为null,不用进行加法计算if(l1 ==null){return l2;}if(l2 ==null){return l1;}int flag =0;ListNode head =newListNode(0);// 数字在链表中逆序存储,需要使用尾插法ListNode p = head;while(l1 !=null&& l2 !=null){int sum = l1.val + l2.val + flag;
flag = sum /10;// 这样计算进位更简洁
sum = sum %10;// 创建新节点,使用尾插法插入到新链表中
p.next =newListNode(sum);
p = p.next;// 更新l1和l2
l1 = l1.next;
l2 = l2.next;}// l1有剩余while(l1 !=null){int sum = l1.val + flag;
flag = sum /10;
sum = sum %10;
p.next =newListNode(sum);
p = p.next;
l1 = l1.next;}// l2有剩余while(l2 !=null){int sum = l2.val + flag;
flag = sum /10;
sum = sum %10;
p.next =newListNode(sum);
p = p.next;
l2 = l2.next;}if(flag ==1){
p.next =newListNode(1);
p = p.next;}
p.next =null;return head.next;}