把2019分成若干个素数相加,求有多少种分法?
元素完全相同的算同一种方法,比如2+2017=2019和2017+2=2019
package DP;
public class 质数分解2019 {
static long res = 0;
static int primes[] = new int[2019];
static long f[][] = new long[350][2100];
public static void main(String[] args) {
for (int i = 0; i < 350; i++) {
for (int j = 0; j < 2100; j++) {
f[i][j] = -1;
}
}
int cnt = 0;
for (int i = 2; i <= 2019; i++) {//初始化1~2019的所有素数
if (isPrimes(i)) {
primes[++cnt] = i;
}
}
//记忆化搜索
System.out.println(dfs(1, 2019));
//一维DP
dp_1D();
//二维DP
dp_2D();
}
private static void dp_2D() {
long a[][]= new long[307][2020];
for(int i = 0; i <= 306; i ++) a[i][0] = 1;
for(int i=1;i<=306;i++) {
for(int j = 0; j <= 2019; j ++) {
a[i][j] = a[i-1][j];
if(j-primes[i]>=0)
a[i][j] += a[i-1][j-primes[i]];
}
}
long max = 0;
for(int i = 1; i <=306; i++) {
max = Math.max(max, a[i][2019]);
}
System.out.println(max);
}
private static void dp_1D() {
long a[]= new long[2020];
a[0] = 1;
for(int i=1;i<=306;i++) {
for(int j = 2019 ; j >=0; j --) {
if(j-primes[i]>=0) a[j] += a[j-primes[i]];
}
}
System.out.println(a[2019]);
}
private static long dfs(int i, int j) {
if (j == 0) return 1;
if (i > 306 || j < primes[i])return 0;
if (f[i][j] != -1)return f[i][j];
f[i + 1][j-primes[i]] = dfs(i + 1, j - primes[i]);
f[i + 1][j] = dfs(i + 1, j);
return f[i][j] = f[i + 1][j-primes[i]] + f[i + 1][j];
}
private static boolean isPrimes(int x) {
for (int i = 2; i <= x / i; i++) {
if (x % i == 0)
return false;
}
return true;
}
}