题目:给你一个数N,确定一个正整数集合S,使得S中的数字的LCM为N且S中数字之和最小。
分析:数论。首先,有一个结论S中的元素互质,因为如果不互质LCM不变,且和更大。
既然S中元素互质,那么只要将N因式分解即可,且相同的因子只能组成一个数字;
(这里先不考虑N等于1或者素数的情况)
即S = { 2^a1, 3^a2, ..., prime(k)^ak },且其中每个因子均大于1;
因此直接加和的结果小于其中某些项想成之后在相加的结果,因此结果为S中元素之和;
注意素数和1的情况。
说明:看错题了,一位只能拆两个数,打表+dpWA了两次才发现看错了╮(╯▽╰)╭。
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
int prime[50001];
int visit[50001];
int divid[32];
int F[50001];
int gcd(int a, int b)
{
return a%b?gcd(b, a%b):b;
}
int main()
{
//计算素数
memset(visit, 0 ,sizeof(visit));
int count = 0;
for (int i = 2 ; i < 50000 ; ++ i) {
visit[i] = 1;
prime[count ++] = i;
for (int j = i+i ; j < 50000 ; j += i)
visit[j] = 1;
}
int N,T = 1,M;
while (~scanf("%d",&N) && N) {
//因式分解,同一因子只属于同一个数中
int M = N,number = 0;
for (int i = 0 ; i < count ; ++ i)
if (N%prime[i] == 0) {
divid[number] = 1;
while (N%prime[i] == 0) {
divid[number] *= prime[i];
N /= prime[i];
}
number ++;
}
if (N > 1) divid[number ++] = N;
while (number <= 1) divid[number ++] = 1;
long long sum = 0;
for (int i = 0 ; i < number ; ++ i)
sum += divid[i];
printf("Case %d: %lld\n",T ++,sum);
}
return 0;
}
原文:http://blog.csdn.net/mobius_strip/article/details/44057905