题意:选择k个素数,使得和为N(1120)的方案数;
筛选出 <= N 的素数,然后就背包
写的时候没初始dp[0][0] = 1;而且方案数也没相加,真是弱逼
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int Max = 1120; int prime[Max + 5], total,flag[Max + 5]; int dp[Max + 5][20]; void get_prime() { total = 0; memset(flag, 0, sizeof(flag)); for(int i = 2; i <= Max; i++) { if(flag[i] == 0) { prime[ ++total ] = i; for(int j = i; j <= Max / i; j++) flag[j * i] = 1; } } } int main() { get_prime(); int n,k; while(scanf("%d%d", &n, &k) != EOF) { if(n == 0 && k == 0) break; memset(dp, 0, sizeof(dp)); dp[0][0] = 1; //初始 for(int i = 1; i <= total; i++) //对于每一个素数进行判断 { for(int j = n; j >= prime[i]; j--) //对于每一个能选择素数的判断 { for(int m = 1; m <= k; m++) //选择的个数可以使1 ... k { if(dp[j - prime[i]][m - 1] != 0) dp[j][m] += dp[j - prime[i]][m - 1]; //当前状态选择m个素数和为j == 选择m - 1个素数合为 j - prime[i] } } } printf("%d ", dp[n][k]); } return 0; }