给出一个整数n,将n分解为至少两个整数之和,使得这些整数的乘积最大化,输出能够获得的最大的乘积。
例如:
2=1+1,输出1;
10=3+3+4,输出36。
很简单:动态规划
//整数成绩最大化 #include<bits/stdc++.h> using namespace std; int main(){ int n,aim,j,i; int tem,a,b; int res[10000]={0};//用来存到该位置的最大值 while(scanf("%d",&n)!=EOF){ res[1]=1; if(n==1){ ; }else{ for(aim=2;aim<=n;aim++){//计算到i tem = 1; for(i=1;i<=aim/2;i++){ j = aim-i; a = i; b=j; if(a<res[i]){ a = res[i]; } if(b<res[j]){ b = res[j]; } if(a*b>tem){ tem = a*b; } } res[aim]=tem; } } printf("%d\n",res[n]); } return 0; }
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int three = n / 3; if (((n - three * 3) & 1) == 1) { three--; } int two = (n - three * 3) / 2; int result = (int)(Math.pow(3, three) * Math.pow(2, two)); System.out.println(result); } }
解释:最大收益是3,余数为1则分给其中一个3,得到4,余数为2则乘上去 所以只需要列举出递推的前三项,第4、5、6项,然后递推a[i]=a[i-3]*3 为什么不是最大收益不是4以上呢?例如5,5可分解为2*3收益能通过继续分解得到增加。 前几个并不能通过递推公式得到,所以列举出来。 1. num = int(input()) 2. resultList = [0,0,1,2,4,6,9] 3. if num<7: 4. print(resultList[num]) 5. else: 6. for i in range(7,num+1): 7. resultList.append(resultList[i-3]*3) 8. print(resultList[num])
import java.util.Scanner; public class Main { /* * 举例计算11,11=5+6,5*6=30,11=3+4+5,3*4*4=48,11=2+3+3+3,2*3*3*3=54,11=1 */ static int p(int num) { int maxMul = 1; //i表示分解为i个数的加法,这些数相差不超过1.在所有的分解法中选择乘积最大的。 for (int i = 2; i < num; i++) { int rem = num % i; int quo = num / i; int mul = 1; // int j=1; for (int j = 1; j <= i - rem; j++) mul *= quo; for (int j = 1; j <= rem; j++) mul *= (quo + 1); if (mul > maxMul) maxMul = mul; else return maxMul; } return maxMul; } public static void main(String[] args) { // TODO Auto-generated method stub // int num=2; // num=10; Scanner scanner=new Scanner(System.in); // 返回:从输入信息扫描的 int int num=scanner.nextInt(); System.out.println(p( num)); } }
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int sum = (int)Math.pow(3, (n / 3 - 1)); if(n % 3 == 1) sum *= 4; if(n % 3 == 2) sum *= 3 * 2; if(n % 3 == 0) sum *= 3; System.out.println(sum); } }
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner in = new Scanner(System.in); int num = in.nextInt(); System.out.println(Doit(num)); } //最优化问题,尽量都分成3,不足部分就分成2 public static long Doit(int num) { long result = 1; while(num>4){ result = result*3; num=num-3; } result = result * num; return result; } }
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); if(n <= 3){ System.out.println(n - 1); }else{ int res = 1; while(n > 4){ res *= 3; n -= 3; } System.out.println(res * n); } } }
def solution(n): if n<=3:return n-1 if n==4:return n if n>4: if n % 3 ==2: return 2 * 3**(n//3) elif n %3 ==1: return 4*3**(n//3-1) else: return 3**(n//3) if __name__ =='__main__': n = int(input().strip()) print(solution(n))
#include<bits/stdc++.h> using namespace std; int a[6]={0,0,1,2,4,6}; int cal(int x,int y) { if(x<6&&y==0) { return a[x]; } else { if(x-3==0) return 3; if(x-3==1) return 4; if(x==5) return 6; if(x>5) return 3*cal(x-3,1); } return 0; } int main() { int n,i; long long ans; scanf("%d",&n); n=abs(n); ans=cal(n,0); printf("%lld\n",ans); }
class MainActivity: def main(self): # Read the data n = int(input()) # Initialization maxProd = [1] # Traverse for num in range(1, n): realNum = num + 1 tmpResult = float('-inf') for subtractNum in range(1, realNum): subtractResult = realNum - subtractNum subtractResultIdx = subtractResult - 1 tmpResult = max(tmpResult, subtractNum * maxProd[subtractResultIdx], subtractNum * subtractResult) maxProd.append(tmpResult) print(maxProd[-1]) if __name__ == '__main__': M = MainActivity() M.main()
这个时间复杂度应该在O(n²)的样子,AC运行时间是45ms。
class MainActivity: def main(self): # Read the data n = int(input()) # Initialization result = float('-inf') # Traverse for k in range(1, n + 1): if n % k: lowNum = n // k highNum = lowNum + 1 result = max(result, lowNum ** (k * lowNum + k - n) * highNum ** (n - k * lowNum)) else: result = max(result, (n // k) ** k) print(result) if __name__ == '__main__': M = MainActivity() M.main()遍历的时间复杂度是O(n),但我感觉乘方也挺耗时间的,看乘方做快速幂优化才行吧。
import java.util.*; public class Main{ public static int[] res; public static int solu(int n){ if (n <= 1) return 1; if (res[n] != 0) return res[n]; int maxValue = 0; for (int i = 1;i<=n;i++){ maxValue = Math.max(maxValue, i * Main.solu(n-i)); } res[n] = maxValue; return maxValue; } public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = Integer.parseInt(sc.nextLine()); Main.res = new int[n+1]; if (n == 2){System.out.println(1);} if (n == 3){System.out.println(2);} else{ System.out.println(Main.solu(n)); } } }
// 动态规划 import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] dp = new int[n+1]; dp[0] = 1; dp[1] = 1; for(int i = 2; i <= n; i++){ for(int j = 1; j <= i/2; j++){ dp[i] = Math.max(dp[i], Math.max(j,dp[j])*Math.max((i-j),dp[i-j])); } } System.out.println(dp[n]); } }
#include<bits/stdc++.h> using namespace std; inline int getRes(int x) { if(x==2) return 1; if(x==1) return 1; if(x<0) return 1; if(x==3) return 3; int sum = 1; while(x>4) { sum = sum*3; x-=3; } return sum *x; } int main(void) { int f;cin>>f; cout << getRes(f) <<endl; }
#include <stdio.h> #define MAXN 1010 long long n; long long ans[MAXN]; long long max(long long a,long long b); int main() { long long i,j; ans[1] = 1; ans[2] = 2; for(i=3;i<MAXN;i++) for(j=1;j<=(i>>1);j++) if(max(j,ans[j])*max(i-j,ans[i-j])>ans[i]) ans[i] = max(j,ans[j]) * max(i-j,ans[i-j]); scanf("%lld",&n); printf("%lld\n",ans[n]); return 0; } long long max(long long a,long long b) { return a>b?a:b; }
import java.util.Scanner; public clas***ain { public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); if (n == 1 || n == 2) { System.out.println(1); return; } int res = 0; for (int i = 2; i <= n / 2; i++) { int a = n / i; int b = n - a * i; if (b != 0){ re***ath.max(res, (int)Math.pow(a,i)*b); } else { re***ath.max(res, (int)Math.pow(a,i)); } } System.out.println(res); } }