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;
}