题目
描述 Description
任何大于 1 的自然数n都可以写成若干个大于等于2且小于等于n的质数之和表达式(包括只有一个数构成的和表达式的情况),并且可能有不止一种质数和的形式。例如,9 的质数和表达式就有四种本质不同的形式:
9=2+5+2=2+3+2+2=3+3+3=2+7。
这里所谓两个本质相同的表达式是指可以通过交换其中一个表达式中
参加和运算的各个数的位置而直接得到另一个表达式。
试编程求解自然数n可以写成多少种本质不同的质数和表达式。
输入格式 Input Format
一行存放一个自然数n(2<= n <=500)。
输出格式 Output Format
输出自然数n的本质不同的质数和表达式的数目。
样例输入 Sample Input
2
样例输出 Sample Output
1
时间限制 Time Limitation
1s
来源 Source
安徽省选2004
题解
看懂题后就发现这其实就是一个要把背包正好放满的完全背包
省选题真的gou啊
CODE
#include <bits/stdc++.h>
#define up(i, a, b) for(register int i = a; i <= b; ++i)
#define down(i, a, b) for(register int i = a; i >= b; i--)
using namespace std;
const int MAXX = 550;
typedef long long ll;
inline int read() {
int s = 0, w = 1;
char ch = getchar();
while (!isdigit(ch)) { if(ch == '-') w = -1; ch = getchar(); }
while (isdigit(ch)) { s = (s << 1) + (s << 3) + (ch ^ 48); ch = getchar(); }
return s * w;
}
int n, cnt = 0;
int a[MAXX], f[MAXX];
inline bool isprime(int k) {
if(k == 1 || k == 0) return false;
if(k == 2) return true;
for(int i = 2; i <= sqrt(k); ++i) {
if(k % i == 0) return false;
}
return true;
}
int main() {
memset(f, 0, sizeof(f));
n = read(); f[0] = 1;
for (register int i = 2; i <= n; ++i) {
if(isprime(i)) {
a[++cnt] = i;
}
}
for (register int i = 1; i <= cnt; ++i) {
for (register int j = a[i]; j <= n; ++j) {
f[j] += f[j - a[i]];
}
}
printf("%d\n", f[n]);
return 0;
}