质数和分解
分析:
本题可以参考集合求数~~
分解成质数之和,所以首先得求素数。由于本题数据不大,打个暴力也行。由于可以分解为多个相同质数的和,所以本题是完全背包。
f[i][j]表示前i个素数和为j的方案数,对于第i个素数,有取和不取两种方案,本题有是求方案数,转移方程就成了:f[i][j]=f[i-1][j]+f[i-1][j-w[i]] (w数组从小到大存求得的素数)。
程序:
二维:
#include <bits/stdc++.h>
using namespace std;
int n,m,w[510];
bool a[510]={};
long long f[510][1010]={};//由于方案数较大,所以会超int
int main()
{
cin>>n;
for (int i=2;i<=sqrt(n*1.0);i++)
if (!a[i])
for (int j=2;j<=n/i;j++)
a[i*j]=true;//筛法求素数
m=0;
for (int i=2;i<=n;i++)
{
if (!a[i])
w[++m]=i;
}//素数存到w数组里
for (int i=1;i<=m;i++)
f[i][0]=1;
for (int i=1;i<=m;i++)
for (int j=1;j<=n;j++)
{
f[i][j]=f[i-1][j];
if (j>=w[i])
f[i][j]+=f[i][j-w[i]];
}//dp完全背包求方案数
cout<<f[m][n];
return 0;
}
一维:
#include <bits/stdc++.h>
using namespace std;
int n,m,w[510];
bool a[510]={};
long long f[510]={};
int main()
{
cin>>n;
for (int i=2;i<=sqrt(n*1.0);i++)
if (!a[i])
for (int j=2;j<=n/i;j++)
a[i*j]=true;
m=0;
for (int i=2;i<=n;i++)
{
if (!a[i])
w[++m]=i;
}
f[0]=1;
for (int i=1;i<=m;i++)
for (int j=w[i];j<=n;j++)
f[j]+=f[j-w[i]];
cout<<f[n];
return 0;
}
打代码不能手残~~~~~~