將 n (2 ≤ n ≤ 150) 個無差別志願者分成若干組,每組人數必須為質數,求分組方案數。順序不分 (即整數分拆,部分限制為質數)。
dp[i] 表示人數和為 i 的合法分組方案數。p,dp[i] += dp[i-p] (為避免重複計數,外層循環質數,內層循環人數,即完全背包「組合數」模板)。dp[0] = 1 (空分組 1 種)。#include
using namespace std;
const int MAXN = 150;
int main() {
vector primes;
vector isPrime(MAXN + 1, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i <= MAXN; ++i) {
if (isPrime[i]) {
primes.push_back(i);
for (int j = i * i; j <= MAXN; j += i) isPrime[j] = false;
}
}
vector dp(MAXN + 1, 0);
dp[0] = 1;
for (int p : primes) { // 外層質數:保證組合不重複
for (int i = p; i <= MAXN; ++i) { // 內層人數:完全背包
dp[i] += dp[i - p];
}
}
int C; cin >> C;
while (C--) {
int n; cin >> n;
cout << dp[n] << endl;
}
return 0;
}
符合樣例輸出。
long long (64位) 或大整數 (n=150 時約 10^10 級)。