Project Euler 618

Project Euler 618

题目

Numbers with a given prime factor sum

Consider the numbers 15, 16 and 18:

15=3×5 and 3+5=8. 16=2×2×2×2 and 2+2+2+2=8.

18=2×3×3 and 2+3+3=8. 15, 16 and 18 are the only numbers that have 8 as sum of the prime factors (counted with multiplicity).

We define S(k) to be the sum of all numbers n where the sum of the prime factors (with multiplicity) of n is k. Hence S(8)=15+16+18=49.

Other examples: S(1)=0, S(2)=2, S(3)=3, S(5)=5+6=11.

The Fibonacci sequence is F1=1, F2=1, F3=2, F4=3, F5=5, Find the last nine digits of k=224S(Fk).

解决方案

本题使用动态规划(递推)思路解决,其阶段性特征比较明显。

p 为存放质数的数组,f(i,j)(i,j0) 为使用了前 i 种质数,质因数之和为 j 的所有数的和。可以列出以下递推方程:

f(i,j)={1ifj=00else ifi=0f(i1,j)else ifj<p[j]f(i1,j)+f(i,jp[i])×p[i]else

那么对于方程最后一行,有以下情况:

  1. 直接把前只使用 i1 素数的情况转移过来。
  2. f(i,jp[i]) 中的所有数全部都添加一个质因数(也就是说,都乘一个 p[i]),就变成了 f(i,j) 的情况,由此就能做到不重不漏的情况。

F24 以内的质数预处理出来,假设有 m 个。那么答案为 k=224f(m,Fk)

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=100000,Q=24;
bool b[N+4];
int pr[N+4],m=0;
int que[144],p=0;
ll f[N+4],mod=1e9;
int main(){
for(int i=1,a=1,b=2;i<Q;i++){
que[++p]=a;
int c=a+b;
a=b;b=c;
}
int mx=que[p];
for(int i=2;i<=mx;i++){
if(b[i]) continue;
pr[++m]=i;
for(int j=i+i;j<=mx;j+=i)
b[j]=1;
}
f[0]=1;
for(int i=1;i<=m;i++)
for(int j=pr[i];j<=mx;j++)
f[j]=(f[j]+f[j-pr[i]]*pr[i])%mod;
ll ans=0;
for(int i=1;i<=p;i++)
ans=(ans+f[que[i]])%mod;
printf("%lld\n",ans);
}