剪绳子Ⅰ
思路:
本题算法思想跟代码不是大问题,主要是数学推导。
通过劈里啪啦一通推导(看不看的,知道结论就完事儿了 ),结论是绳子以长度为3时等分效果为好,乘积最大。
其实问题变转化为,数字n,怎样除以3,使得各个商的乘积最大。
- 当n<=3时,没有什么规律可言,最大商就是n-1(自己品品,你品!)
- 当n>3时,n=3*a+b
b的结果,无非有三种,0,1,2
好了,破案!!!!!!!!!!!!!
上代码:
class Solution {
public int cuttingRope(int n) {
if(n<=3){
return n-1;
}
int a=n/3;
int b=n%3;
if(b==0){
return (int)Math.pow(3,a);
}
else if(b==1){
return (int)Math.pow(3,a-1)*4;
}
else{
return (int)Math.pow(3,a)*b;
}
}
}
剪绳子Ⅱ
思路:
有了剪绳子Ⅰ的前情铺垫,到了Ⅱ,就知道咋剪了。言归正传。
这个题的难点在于
大数求余
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/07eff04df8ad7fb3a7a5ff9974ac75ed.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/ac3140b17f992ab2f2b2928487e72ae1.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/57c4ea11c549a128c9a0f6ab9be912af.png)
本次解法采用的是快速幂求余,上代码:
class Solution {
public int cuttingRope(int n) {
if(n<=3){
return n-1;
}
int a;
int b=n%3;
long ji=1L;
long x=3L;
int p=1000000007;
for(a=n/3-1;a>0;a/=2){
if(a%2==1){
ji=(ji*x)%p;
}
x=(x*x)%p;
}
if(b==0){
ji=(ji*3)%p;
}
else if(b==1){
ji=(ji*4)%p;
}
else{
ji=(ji*6)%p;
}
return (int)ji;
}
}
后面附上循环求余法:
class Solution {
public int cuttingRope(int n) {
if(n <= 3) return n - 1;
long res=1L;
int p=(int)1e9+7;
//贪心算法,优先切三,其次切二
while(n>4){
res=res*3%p;
n-=3;
}
//出来循环只有三种情况,分别是n=2、3、4
return (int)(res*n%p);
}
}