給定 n 和 k,求將 n 表示為 k 個不同質數之和的方案數。質數不重複使用,屬於 01 背包問題。
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int MAXN = 1120;
const int MAXK = 15;
int dp[MAXN+1][MAXK];
vector<int> primes;
void sieve() {
vector<bool> isPrime(MAXN+1, true);
isPrime[0] = isPrime[1] = false;
for(int i = 2; i*i <= MAXN; i++)
if(isPrime[i])
for(int j = i*i; j <= MAXN; j += i)
isPrime[j] = false;
for(int i = 2; i <= MAXN; i++)
if(isPrime[i]) primes.push_back(i);
}
int main() {
sieve();
int n, k;
while(scanf("%d%d", &n, &k) == 2 && (n || k)) {
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for(int p : primes) {
for(int i = n; i >= p; i--)
for(int j = 1; j <= k; j++)
dp[i][j] += dp[i-p][j-1];
}
printf("%d\n", dp[n][k]);
}
return 0;
}
經典 01 背包變體:物品為質數,重量=價值=質數值,限制物品數量為 k。逆序更新是關鍵。