【问题描述】
将 2019 拆分为若干个两两不同的质数之和,一共有多少种不同的方法? 注意交换顺序视为同一种方法,例如 2 + 2017 = 2019 与 2017 + 2 = 2019 视为同一种方法。
题目其实不难,自己比赛的时候也是想到做法了,结果算出来的数贼大,感觉自己算错了。。。哎。。
做法:(可能不是最佳的做法)
先获得2019内的所有素数,然后就是一个从N个数里面凑成M的个数的题目了。
类似leetcode 494 目标和的题目了。直接01背包
d p [ j ] = d p [ j − a [ i ] ] + d p [ j ] dp[j] = dp[j-a[i]] + dp[j] dp[j]=dp[j−a[i]]+dp[j]dp[j]表示j能凑成的种类数。a[i]表示第i个素数。
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX = 3000;
ll dp[MAX];
bool isprime(ll x){
if(x < 2) return false;
else if(x == 2) return true;
else{
for(ll i=2;i*i<=x;++i){
if(x % i == 0)
return false;
}
return true;
}
}
void solve(ll num){
vector<ll> vec;
for(ll i=1;i<=num;++i){
if(isprime(i))
vec.push_back(i);
}
memset(dp,0,sizeof(dp));
dp[0] = 1;
for(int i=0;i<vec.size();++i){
for(int j=num;j>=vec[i];--j){
dp[j] += dp[j-vec[i]];
}
}
printf("%lld\n",dp[num]);
}
int main(void){
solve(2019);
return 0;
}