题目
问题描述
给出一个正整数n,求一个和最大的序列a0,a1,a2,……,ap,满足n=a0>a1>a2>……>ap且ai+1是ai的约数,输出a1+a2+……+ap的最大值
输入格式
输入仅一行,包含一个正整数n
输出格式
一个正整数,表示最大的序列和,即a1+a2+……+ap的最大值
样例输入
10
样例输出
6
题解
很简单的一个算法题目,直接就是贪心思路:求每一个数字的最大约数,然后到1就行了。时间复杂度 O ( m a x ( l o g n , n ) ) O(max(logn, \sqrt{n})) O(max(logn,n))
举个例子:15,求最大约数为5。 然后5求最大约数为1,那么这种情况就是最优的。和为5 + 1 = 6
证明:
- a0越大后面的数字才有可能越多
- a0越大,后面的数字才有可能越大。
因为上面两条性质,所以,a0取最大的时候,也就是最大约数时,答案才会最大。
- c++代码
(看很多喜欢看c++代码的,以后都顺便写了吧)
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
int ans = 1;
while (n != 1) {
int up = (int)sqrt(n + 1);
int flag = 0;
for (int i = 2; i <= up; i++) {
if (n % i == 0) {
n /= i;
flag = 1;
break;
}
}
if (flag) ans += n;
else n = 1;
}
cout << ans <<endl;
}
- java代码
package lanqiao;
import java.util.Scanner;
/**
* @author: Zekun Fu
* @date: 2022/10/13 23:43
* @Description: 最大分解
* 直接求每一个数字的最大约数就行了。
* 直到求的数字是一个素数,然后直接到1就可以了。
*/
public class MaxFenJie {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int ans = 1;
while (n != 1) {
int up = (int)Math.sqrt(n + 1);
int flag = 0;
for (int i = 2; i <= up; i++) {
if (n % i == 0) {
n /= i;
flag = 1;
break;
}
}
if (flag == 1) ans += n;
else break;
}
System.out.println(ans);
}
}