题目:给你一根长度为 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
动归
int cuttingRope(int n) {
if(n==2) return 1;
if(n==3) return 2;
vector<int> dp(n+1,0);
dp[0]=0;
dp[1]=1;
dp[2]=2;
dp[3]=3;
for(int i=4;i<=n;i++){
for(int j=1;j<=i/2;j++){
dp[i]=max(dp[i],dp[j]*dp[i-j]);
}
}
return dp[n];
}
贪婪
class Solution {
public:
#define MOD 1000000007;
int cuttingRope(int n) {
if(n==2) return 1;
if(n==3) return 2;
int b=n%3;
int mi;
if(b==0){
mi=n/3;
return quickPow(3,mi);
}
else if(b==1){
mi=n/3-1;
return quickPow(3,mi)*4%MOD;
}
else{
mi=n/3;
return quickPow(3,mi)*2%MOD;
}
}
};
快速幂
long long quickPow(long long n,long long mi){
long long ans=1;
while(mi){
if(mi&1){
ans=(ans*n)%MOD;
}
n=n*n%MOD;
mi>>=1;
}
return ans;
}
快速幂2
考虑小数底和负数幂
double myPow(double x, int n) {
if(x==1.0||x==0) return x;
if(n==0) return 1;
double ans=1.0;
long b = (long)n;//防止溢出强制转换
if (b < 0)//处理负数
{
b = -b;
x = 1/x;
}
while(b){
if(b&1){
ans=x*ans;
}
x=x*x;
b>>=1;
}
return ans;
}