WATEROJ
你们给我好好取名字啊!魂淡!这是交作业的地方啊! Nickname 请用真名!
1007: 数的分解
Time Limit: 1 Sec Memory Limit: 32 MBSubmit: 87 Solved: 62
[ Submit][ Status][ Web Board]
Description
大于1的正整数n可以分解为:n=x1*x2*…*xm。 (xi != 1 )
例如,当n=12 时,共有8 种不同的分解式:
12=12; 12=6*2; 12=4*3; 12=3*4; 12=3*2*2; 12=2*6; 12=2*3*2; 12=2*2*3。
当n为质数时,至少也有一种分解法:n = n。
对于给定的正整数n,计算n共有多少种不同的分解式。
Input
多组数据,可能会有超过10000组。
每组数据输入一行整数N。(0 < N < = 3000)
Output
每组数据输出一行整数M,表示对整数N有多少种分解方法。
Sample Input
4
3
8
12
Sample Output
2
1
4
8
HINT
4 = 2 * 2 = 4
3 = 3
8 = 2 * 4 = 2 * 2 * 2 = 4 * 2 = 8
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<math.h>
using namespace std;
int main() {
int n;
while (scanf("%d", &n) != EOF) {
int f[3001]; //f[i]对应对i进行因式分解的种类的最大数量
int s[3001]; //s[i]用于记录对n进行因式分解时的因子
int k = 0;
for (int i = 0; i < 3001; i++)
f[i] = 1; //对任何数n,均能进行 最少一次的因式分解,即 n = 1 * n
//该步主要为求得n的所有只带一个乘号的因子,如n = 12时, 2 * 6, 3 * 4, 4 * 3, 6 *2, s[0..3]为 2,3,4,6
for (int i = 2; i <= n/2; i++)//该数的因式分解的动态规划,即问题求解转化为子问题求解,
//当前状态与前一状态有关,对于数的因式分解,子问题其实只与该数的因子有关,此处是为了减少下面循环的次数,防止超时(刚开始超时原因所在)
if (n % i == 0)
s[k++] = i;
s[k] = n;
//以下使用了动态规划的自底向上
for (int i = 0; i <= k ; i++) {
//对n中在s中记录的每个因子继续分解,求得其最大能够被分为的种类数,即体现了大问题转化为小问题思想
for (int j = 2; j <= s[i]/2; j++) {
if (s[i] % j == 0) {
f[s[i]] += f[j]; //或者f[s[i]] += f[s[i]/j] 如果为s[i]的因子,则查表获得j的最大能够被分为的种类数
}
}
}
cout << f[n] << endl;//f[n]即为对n进行因式分解所得的最大种类数
}
//system("pause");
return 0;
}
/**************************************************************
Problem: 1007
User: 12330344
Language: C++
Result: Accepted
Time:800 ms
Memory:1268 kb
****************************************************************/