2013
11-12

# Sum of Different Primes

A positive integer may be expressed as a sum of different prime numbers (primes), in one way or another. Given two positive integers n and k, you should count the number of ways to express n as a sum of k different primes. Here, two ways are considered to be the same if they sum up the same set of the primes. For example, 8 can be expressed as 3 + 5 and 5 + 3 but the are not distinguished.

When n and k are 24 and 3 respectively, the answer is two because there are two sets {2, 3, 19} and {2, 5, 17} whose sums are equal to 24. There are not other sets of three primes that sum up to 24. For n = 24 and k = 2, the answer is three, because there are three sets {5, 19}, {7, 17} and {11, 13}. For n = 2 and k = 1, the answer is one, because there is only one set {2} whose sum is 2. For n = 1 and k = 1, the answer is zero. As 1 is not a prime, you shouldn’t count {1}. For n = 4 and k = 2, the answer is zero, because there are no sets of two different primes whose sums are 4.

Your job is to write a program that reports the number of such ways for the given n and k.

The input is a sequence of datasets followed by a line containing two zeros separated by a space. A dataset is a line containing two positive integers n and k separated by a space. You may assume that n ≤ 1120 and k ≤ 14.

The output should be composed of lines, each corresponding to an input dataset. An output line should contain one non-negative integer indicating the number of the ways for n and k specified in the corresponding dataset. You may assume that it is less than 231.

24 3
24 2
2 1
1 1
4 2
18 3
17 1
17 3
17 4
100 5
1000 10
1120 14
0 0

2
3
1
0
0
2
1
0
1
55
200102899
2079324314

//* @author:
import java.io.BufferedInputStream;
import java.util.ArrayList;
import java.util.Scanner;

public class Main {

static ArrayList< Integer> primes = Prime.getPrimes(1120);

public static void main(String[] args) {
int[][] f = new int[1140][1140];
Scanner scan = new Scanner(new BufferedInputStream(System.in));
f[0][0] = 1;
for (int j = 0; j < primes.size(); j++) {
for (int i = 14; i >= 1; i--) {
for (int v = 1120; v > 0; v--) {
if (v - primes.get(j) >= 0) {
f[i][v] += f[i - 1][v - primes.get(j)];
}
}
}
}
while (scan.hasNext()) {
int n = scan.nextInt();
int k = scan.nextInt();
if (n == 0 && k == 0) {
break;
}
System.out.println(f[k][n]);
}
}
}

class Prime {

public static ArrayList getPrimes(int n) {
int i, j, k, x, num;
n++;
n /= 2;
int[] b = new int[(n + 1) * 2];
ArrayList a = new ArrayList();
num = 2;
for (i = 1; i <= 2 * n; i++) {
b[i] = 0;
}
for (i = 3; i <= n; i += 3) {
for (j = 0; j < 2; j++) {
x = 2 * (i + j) - 1;
while (b[x] == 0) {
for (k = x; k <= 2 * n; k += x) {
b[k] = 1;
}
}
}
}
return a;
}
}

1. 在方法1里面：

//遍历所有的边，计算入度
for(int i=0; i<V; i++)
{
degree = 0;