动态规划解题---数的因式分解
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 ****************************************************************/