UVA

来源:互联网 发布:2016年心动网络招聘 编辑:程序博客网 时间:2024/05/22 06:52

题意:

给一个n和k,求k个素数的和为n的方案数。和0 1背包很像

A positive integer may be expressed as a sum of different prime numbers (primes), in one way oranother. Given two positive integersn andk, you should count the number of ways to expressn as asum ofk different primes. Here, two ways are considered to be the same if they sum up the same setof the primes. For example, 8 can be expressed as 3 + 5 and 5 + 3 but they are not distinguished.

When nand kare 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 no other sets of three primes that sum up to 24. Forn= 24 and k= 2, the answer is three, because there are three sets{5,19},{7,17}and {11,13}. Forn=2andk=1,theanswerisone,becausethereisonlyoneset{2}whosesumis2. Forn=1andk=1,theansweriszero. As1isnotaprime,youshouldn’tcount{1}. Forn=4andk=2,theanswer 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 givenn andk.Input

The input is a sequence of datasets followed by a line containing two zeros separated by a space. Adataset is a line containing two positive integersn andk separated by a space. You may assume thatn1120 andk 14.

Output

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

Sample Input

24 3
24 221
11
42
18 3
17 1
17 3
17 4100 51000 101120 1400

Sample Output

231002101552001028992079324314
#include<iostream>#include<algorithm>#include<string>#include<sstream>#include<set>#include<vector>#include<stack>#include<map>#include<queue>#include<deque>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<functional>using namespace std;#define N 1200int n, k;typedef long long ll;ll dp[N][20];vector<int>primes;int vis[N];void make_prime(){memset(vis, 0, sizeof(vis));for (int i = 2; i < N;i++)    {        if(!vis[i])        {            for (int j = 2*i; j < N; j += i)                vis[j] = 1;        }    }for (int i = 2; i < N;i++)if (!vis[i])primes.push_back(i);}void cal(){memset(dp, 0, sizeof(dp));int len = primes.size();dp[0][0] = 1;for (int i = 0; i < len; i++)for (int n = N; n >= primes[i];n--)for (int k = 1; k <= 14; k++){dp[n][k] += dp[n - primes[i]][k - 1];}}int main(){    make_prime();cal();while (cin>>n>>k,n+k){cout << dp[n][k] << endl;}return 0;}


原创粉丝点击