任何一个大于1的自然数n都可以携程都可以写成若干个大于等于2小于等于n的质数之和,并不只有一种形式.例如9就有四种形式.
9 = 2 + 5 +2 = 2 + 3 +2 +2 = 3 + 3 +3= 2+ 7
方法一:
直接进行搜索(输入限制很大).
方法二:
构造下列母函数.
G(x) = (1+x^2+x^4+x^6+.....x^(x/2)) (1+x^3+x^6+x^9+...x^(x/3))*.........
说明:
对于没一部分 x^m (1 = x^0) 第 i 部分则是选择第i个质数pirme[i]的个数
最后只需要求得x^n项的系数即可.
然而对于求多个质数则使用筛法来求.
对于一个素数i,其所有的倍数都不是素数,
使用该方法进需要将所有x<n/2 的所有质数的倍数排除,则剩下的 m < n m!=x为质数.
给出代码:
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;
bool temp[201];
int pol[201];
vector<int> prime;
int main(){
int n;
memset(temp,true,sizeof(temp));
prime.clear();
for(int i=2;i<=200;i++){
if(temp[i]){
//printf("%d \n",i); 此处i是素数
prime.push_back(i);
for(int j=i*i;j<=200;j+=i){//所有i的倍数不是素数
temp[j]=false;
}
}
}
return 0;
}
原问题的代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;
bool temp[201];
int pol[201];
vector<int> prime;
int main(){
int n;
memset(temp,true,sizeof(temp));
prime.clear();
for(int i=2;i<=200;i++){
if(temp[i]){
//printf("%d \n",i);
prime.push_back(i);
for(int j=i*i;j<=200;j+=i){
temp[j]=false;
}
}
}
scanf("%d",&n);
memset(pol,0,sizeof(pol));
pol[0]=1;
for(int i=0;i < prime.size() && prime[i] <= n;i++){
for(int j=n;j>=0;j--){
if(pol[j]){
for(int add=prime[i];add+j<=n;add+=prime[i]){
pol[add+j] += pol[j];
}
}
}
}
printf("%d\n",pol[n]);
return 0;
}