9718 整数因子分解(必做) 分治法

9718 整数因子分解(必做)

时间限制:1000MS  内存限制:1000K
提交次数:0 通过次数:0

题型: 编程题   语言: G++;GCC;VC;JAVA

Description

大于1的正整数 n 都可以分解为 n = x1 * x2 * ... * xm, 每个xi为大于1的因子,即1<xi<=n 。

例如:当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 (1<=n<=1000000)

输出格式

不同的分解式数目

输入样例

12

输出样例

8

考虑先暴力写出前几项。数字:1、2、3、4、5、6、7、8、9、10、11、12ans:1、1、1、2、1、3、1、4、2、3 、 1、 8

所以递推式就是fun(val) = val的所有因子的答案加起来(不包括自己, 然后 + 1,就是加上自己)。递归求解即可。

为什么这样是答案呢?因为其是考虑顺序的,那么ans就是第一个数字是2的分拆数总和 + 第一个数字是3的分拆数总和。第一个数字是2的分拆数总和是多少?就是2 * (6的分拆数)递归求解。

提示

此题因子讲顺序的.第一个因子可能是2~n之间的数.

比如对12而言,第一个因子可能是2,3,4,6,12.

将第一个因子为2的分解个数,加上第一个因子为3的分解个数,...,直至加到第一个因子为12的分解个数.

而第一个因子为2的分解个数又是多少呢?是6(因为12/2=6)的分解个数,递归求解!


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 1000000 + 20;
LL dp[maxn];
LL find(int val) {
    if (dp[val]) return dp[val];
    LL ans = 1;
    for (int i = 2; i <= val / 2; ++i) {
        if (val % i != 0) continue;
        dp[i] = find(i);
        ans += dp[i];
    }
    return ans;
}
void work() {
    int n;
    cin >> n;
    dp[1] = 1;
    LL ans = 1;
    for (int i = 2; i <= n / 2; ++i) {
        if (n % i != 0) continue;
        dp[i] = find(i);
        ans += dp[i];
    }
    cout << ans << endl;
}

int main() {
#ifdef local
    freopen("data.txt","r",stdin);
#endif
    work();
    return 0;
}

时间: 2024-11-05 15:52:46

9718 整数因子分解(必做) 分治法的相关文章

大整数乘法(分治法)

题目:输入两个大整数,用数组保存每一位数,然后用分治法计算: 思路:输入X Y,X高位用A数组保存,低位用B数组保存,Y高位用C数组保存,低位用D数组保存,则:X=A*10^(n/2)+B  Y=C*10^(n/2)+D 分治方法:X*Y=A*C*10^n+((A-B)*(D-C)+A*C+B*D)*10^(n/2)+B*D; 代码如下: #include <iostream> #include <algorithm> #include <cstring> #inclu

[算法]:分治法-求大整数相乘

#问题大整数相乘 #思路说明 对于大整数计算,一般都要用某种方法转化,否则会溢出.但是python无此担忧了. Python支持**"无限精度"的整数,**一般情况下不用考虑整数溢出的问题,而且Python Int类型与任意精度的Long整数类可以无缝转换,超过Int 范围的情况都将转换成Long类型. 例如: >>> 2899887676637907866*1788778992788348277389943 51872581574157002360341697913

大整数相乘“分治法”和“循环暴力法”

前言 今天刷到一道很有趣的面试题,感觉很有意思,来分享给大家. 题目描述 有两个用字符串表示的非常大的大整数,算出他们的乘积,也是用字符串表示.不能用系统自带的大整数类型. 输入描述:空格分隔的两个字符串,代表输入的两个大整数输出描述:输入的乘积,用字符串表示 示例1 输入72106547548473106236 982161082972751393输出70820244829634538040848656466105986748 思路分析 例如x=1234,y=567 ①将x拆分成两半儿,a =

分治法(一)

这篇文章将讨论: 1) 分治策略的思想和理论 2) 几个分治策略的例子:合并排序,快速排序,折半查找,二叉遍历树及其相关特性. 说明:这几个例子在前面都写过了,这里又拿出来,从算法设计的策略的角度把它们放在一起来比较,看看分治是如何实现滴.由于内容太多,我将再花一篇文章来写4个之前没有写过的分治算法:1,大整数乘法   2,矩阵乘法的分治策略   3,最近点对  4,凸包问题,请见下一篇. 好了,切入正题. --------------------------------------------

算法实验:分治法合并排序(C++)

这篇文章分两部分来写,第一部分写代码的实现过程,第二部分把实验报告从头到尾呈现出来. 我习惯调试使用的编译器是DEV C++,不是vs系列的,可能头文件上有点区别.但是下面的报告是我放到vs里面测试过的,可以直接用,不影响. 第一部分:(解析) 题目:随机产生一个整型数组,然后用合并排序将该数组做升序排列,要求输出排序前和排序后的数组. 题目分析: 需要随机产生一个整数数组: 采用的算法是合并排序,也就是用归并排序: 输出排序后的数组. 随机产生一个整数数组:这个问题首先想到的是用rand()函

分治法-汉诺塔问题

一 基本概念 分治法,顾名思义分而治之的意思,就是把一个复杂的问题分成两个或很多其它的同样或相似的子问题,再把子问题分成更小的子问题--直到最后子问题能够简单的直接求解,原问题的解即子问题的解的合并. 二基本思想及策略 分治法的设计思想是:将一个难以直接解决的大问题,切割成一些规模较小的同样问题,以便各个击破,分而治之. 分治策略是:对于一个规模为n的问题,若该问题能够easy地解决(比方说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式同样,递归地解

分治法-最近距离问题Java实现

分治算法,有很多典型的问题,如最近点问题.线性选择问题.整数划分问题.大整数成绩问题.棋盘覆盖问题.循环赛日程表.二分搜索.Strassen矩阵乘法.汉诺塔等.准备花些时间逐个解决这些问题,并用Java实现,从最近点问题开始.网上找到一些代码,标题如"java 用蛮力法和分治法求解最近对有关问题",虽然体现了分治,但划分不够彻底,因此我重新对其进行了实现. 一.基本思想及策略: 首先,说说分治的思想.分治, "分而治之",就是把一个复杂的问题分成两个或更多的相同或相

分治法(二)

参考  <算法设计与分析> 第四章 分治法     Anany Levitin著  翻译版   清华大学出版社 在上一篇文章中,介绍了分治策略的思想,主定理,以及几个用分治策略的经典案例.这一篇文章将继续探讨分治算法的其他应用,包括大整数乘法和Strassen矩阵乘法,最近点对问题和凸包问题这4个算法,一般来说常规的数据结构教程上不包括这些内容. --------------------------------------------------------------------------

分治法、动态规划、回溯法、分支界限法、贪心算法

转:http://blog.csdn.net/lcj_cjfykx/article/details/41691787 分治算法一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)…… 任何一个可以用计算机求解的问题所需的计算时