题解:质数和分解

Posted 24Kmagic

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解:质数和分解相关的知识,希望对你有一定的参考价值。

题目:

题目描述

任何大于 111 的自然数 nnn 都可以写成若干个大于等于 222 且小于等于 nnn 的质数之和表达式(包括只有一个数构成的和表达式的情况),并且可能有不止一种质数和的形式。例如,999 的质数和表达式就有四种本质不同的形式:9 = 2 + 5 + 2 = 2 + 3 + 2 + 2 = 3 + 3 + 3 = 2 + 7 。
这里所谓两个本质相同的表达式是指可以通过交换其中一个表达式中参加和运算的各个数的位置而直接得到另一个表达式。
试编程求解自然数 nnn 可以写成多少种本质不同的质数和表达式。

输入格式

文件中的每一行存放一个自然数 n(2≤n≤200) 。

输出格式

依次输出每一个自然数 nnn 的本质不同的质数和表达式的数目。

样例
输入 #1
2
200
输出 #1
1
9845164

解析:

这道题首先用筛法求出一个素数表,由于数据范围是200以内,所以处理到二百稍多一点就够了,然后利用完全背包求解即可

关于不重复的式子:

我们处理的素数是从小到大处理的,我们写背包的时候也是正序循环过去的,所以当我们选完了一个物品我们就不可能再回来选这个物品,因此7 + 2是不会存在的。

代码:

#include<bits/stdc++.h>
using namespace std;
long long v[210],prime[100],num=0,n,dp[300];
void truncsqrt() {
    for(int i = 2; i <= 200; i++) {
	    if(!v[i]) {
		    v[i] = i;
		    prime[++num] = i;
	    }
	    for(int j = 1; j <= num; j++) {
		    if(prime[j] > 200 / i || prime[j] > v[i])
			    break;
		    v[i*prime[j]] = prime[j];
	    }
    }
}
int main() {
    truncsqrt();
    while(scanf("%d" ,&n) != EOF) {    //由题目中“每一行存放一个自然数 n”可以推断出这是多组数据。。。。不要笑,不按多组数据写会卡掉一个点的。。。。。
	    memset(dp,0,sizeof(dp));
	    dp[0] = 1;
	    for(int i = 1; i <= num; i++) {
		    for(int j = prime[i]; j <= n; j++) {
			    dp[j] += dp[j - prime[i]];
		    }
	    }
	    printf("%d\\n",dp[n]);
    }
    return 0;
}

以上是关于题解:质数和分解的主要内容,如果未能解决你的问题,请参考以下文章

约数之和

质数判断(欧拉筛法)

题解单纯质因数

CH 3101 - 阶乘分解 - [埃筛]

[HNOI2001] 求正整数

洛谷 [AHOI2001]质数和分解