Problem Description
給定一個正整數N,將它表示成至少兩個正整數之和(即N=a1+a2+…+ak, k > 1),求a1 × a2 × … × ak的最大值。
例如對N=4來說,共有下面4種不同的方案:
4=1+1+1+1
4=1+1+2
4=1+3
4=2+2
其中最大的乘積是最後一種,最大乘積是2×2=4。
Input
每個輸入文件一組數據。
第一行爲一個正整數N(2<=N<=20)。
Output
輸出一個正整數,表示a1 × a2 × … × ak的最大值。
Sample Input 1
2
Sample Output 1
1
Sample Input 2
4
Sample Output 2
4
Sample Input 3
6
Sample Output 3
9
1、分析
這道題目和浙大PAT甲級真題有點相似,PAT.A.1103 Integer Factorization (30 分),用同樣的方法即可。如果使用枚舉法肯定是不現實的,採用深度優先搜索+剪枝是一個比較好的方法。由於每次進行遞歸的時候都有一個臨時乘積變量,因此枚舉的範圍應該是1~N-1,不能是0~N。
2、代碼
①本題代碼:
#include<stdio.h>
int maxProduct = 0, N;
//index爲當前索引,sum爲當前選出的整數和,product爲當前積
void DFS(int index, int sum, int product){
if(sum == N){ //找出的幾個數的和剛好等於N
if(product > maxProduct){ //找出最大積
maxProduct = product;
}
return;
}
if(sum > N){ //和大於N,直接返回
return;
}
for(int i = index; i < N; i++){ //從index ~ N-1進行枚舉
DFS(i, sum + i, product * i);
}
}
int main(){
scanf("%d", &N);
DFS(1, 0, 1); //注意搜索的起點
printf("%d\n", maxProduct);
return 0;
}
②如果要保存下來取得最大積時選擇的數據可以採用下面的方法,在遞歸的for循環裏面使用vector進行保存,當數據較多時可以在for裏面剪枝,如下:
#include<stdio.h>
#include<vector>
using namespace std;
int maxProduct = 0, N;
void DFS(int index, int sum, int product, vector<int> &ans, vector<int> temp){
if(sum == N){
if(product > maxProduct){
maxProduct = product;
ans = temp;
}
return;
}
if(sum > N){
return;
}
for(int i = index; i < N; i++){ //從index ~ N-1進行枚舉
temp.push_back(i); //加入temp中
if(sum + i > N) break; //剪枝
DFS(i, sum + i, product * i, ans, temp);
temp.pop_back(); //從temp中除去
}
}
int main(){
scanf("%d", &N);
vector<int> ans, temp;
DFS(1, 0, 1, ans, temp); //注意搜索的起點
if(ans.size() == 0) printf("0"); //當輸入1時特判輸出爲0
for(int i = 0; i < ans.size(); i++){
printf("%d", ans[i]);
if(i < ans.size() - 1) printf(" ");
}
return 0;
}
③如果要求有多少種方案,直接使用一個變量,在每次遞歸的時候出現和等於N的時候+1即可
#include<stdio.h>
int N;
void DFS(int index, int sum, int &ans){
if(sum == N){
ans++; //方案數目+1
return;
}
if(sum > N){ //和大於N,直接返回
return;
}
for(int i = index; i < N; i++){ //從index ~ N-1進行枚舉
DFS(i, sum + i, ans);
}
}
int main(){
scanf("%d", &N);
int ans = 0;
DFS(1, 0, ans);
printf("%d\n", ans);
return 0;
}