首页 > 其他 > 详细

poj 3132

时间:2016-02-14 23:33:23      阅读:522      评论:0      收藏:0      [点我收藏+]
Sum of Different Primes
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 3360   Accepted: 2092

Description

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.

Input

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.

Output

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.

Sample Input

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

Sample Output

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

思路:prim[]为素数表;
   f[i][j]为j拆分成i个素数和的方案数(1<=i&&i<=14,prim[i]<=j&&j<=1199) 边界f[0][0]=1;
   int num 为prim[]的表长;
   使用DP计算k个不同素数的和为n的方案总数:
      枚举prim[]中的prim[i](0<=i&&i<=num);
        按递减顺序枚举素数的个数j(14>=j&&j>=1);
           递减枚举前j个素数的和p(1199>=p&&p>=prim[i]);
              累计prim[i]作为第j个素数的方案总数f[j][p]+=f[j-1][p-prim[i]];
      
   f[k][n]即为解!!!!!!
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<iomanip>
 7 #include<cmath>
 8 #include<vector>
 9 #include<queue>
10 #include<stack>
11 using namespace std;
12 #define PI 3.141592653589792128462643383279502
13 #define N 1200
14 int prim[N]={2,3},f[15][N],t;
15 int prime(){
16     int t=2,i,j,flag;
17     for(i=5;i<N;i+=2){
18         for(j=0,flag=1;prim[j]*prim[j]<=i;j++)
19             if(i%prim[j]==0) flag=0;
20         if(flag){
21             prim[t++]=i;
22         }
23     }
24     return t-1;
25 }
26 void s(){
27      for(int i=0;i<=t;i++){
28                 for(int j=14;j>=1;j--){
29                     for(int p=1199;p>=prim[i];p--)
30                         f[j][p]+=f[j-1][p-prim[i]];
31                 }
32             }
33 }
34 int main(){
35     //#ifdef CDZSC_June
36     //freopen("in.txt","r",stdin);
37     //#endif
38     //std::ios::sync_with_stdio(false);
39     t=prime();
40     int k,n;
41     while(scanf("%d%d",&n,&k)){
42         memset(f,0,sizeof(f));
43         f[0][0]=1;
44         if(k==0&&n==0) break;
45         s();
46          cout<<f[k][n]<<endl;
47     }
48     return 0;
49 }

 

poj 3132

原文:http://www.cnblogs.com/yoyo-sincerely/p/5074749.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!