Least common multiple (数论+完全背包)

hdu 3092 Least common multiple(完全背包+数论) Least common multiple Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 437    Accepted Submission(s): 162 Problem Description Partyc 阅读详情

Least common multiple

 Partychen like to do mathematical problems. One day, when he was doing on a least common multiple(LCM) problem, he suddenly thought of a very interesting question: if given a number of S, and we divided S into some numbers , then what is the largest LCM of these numbers? partychen thought this problems for a long time but with no result, so he turned to you for help!
Since the answer can very big,you should give the answer modulo M.

Input
There are many groups of test case.On each test case only two integers S( 0 < S <= 3000) and M( 2<=M<=10000) as mentioned above.
Output
Output the largest LCM modulo M of given S.
Sample Input

6 23

Sample Output

6


Hint: you can divied 6 as 1+2+3 and the LCM(1,2,3)=6 is the largest so we output 6%23=6.
题意:

将一个数拆分成几个数的和,并求出这几个数最小公倍数的最大值,结果模m

分析:

首先我们根据题目意思可以知道,为了让最小公倍数最大,我们需要让分开的每个数都是互质的,这样答案直接就是分成的每个数相乘了。所以我们可以先筛选出1~3000的素数,然后从这些素数里面取或者多个组成n,最后求n填满时最大的LCM,所以是完全背包
dp[i]表示将数i分成若干个数可以得到的最大的最小公倍数

互质存在以下情况:

1) 1和任何自然数互质
2) 两个不同的质数互质
3) 一个质数和一个合数,当他们不是倍数关系时互质
4) 两个合数,当他们不含有相同的质因子时互质

根据算数基本定理我们只需要考虑选择素数或者素数的幂

由于lcm结果过大会溢出,题目要求的结果有取模,但如果在递推dp的过程中取模,在比较选择最优结果时就会出错,例如模数为m,上一次求出dp[k]=m+1,结果取模得1,下一次随便一个大于1得答案就会覆盖掉正确答案。但是不取模就会溢出,肯定也会造成答案错误。这里使用了取log来保存答案

那么对于我们枚举的一个素数p,当前的最小公倍数应该为

dp[j]=dp[j−p]∗pdp[j]=dp[j−p]∗p (因为互质所以直接用j-p这个数可以得到的最大的最小公倍数乘p)

因为会溢出所以取log后实际得到

log(dp[j])=log(dp[j−p])+log(p)log(dp[j])=log(dp[j−p])+log(p)

而对于一般的情况p的幂次

我们得到了

log(dp[j])=log(dp[j−p])+log(pk)=log(dp[j−p])+k⋅log(p)log(dp[j])=log(dp[j−p])+log(pk)=log(dp[j−p])+k⋅log(p)

因此我们直接让dp改使用double类型

就得到递推式

dp[j]=dp[j−p]+k⋅log(p)dp[j]=dp[j−p]+k⋅log(p)

通过dp比较大小,通过ans数组记录实际的取模值

code:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int n,m;
int prime[1000];
bool isprime[3005];
double dp[3005];
int ans[3005];
int num;
void init(){
    num = 0;
    memset(isprime,true,sizeof(isprime));
    isprime[0] = isprime[1] = false;
    for(int i = 2; i <= 3000; i++){
        if(isprime[i]){
            prime[num++] = i;
            for(int j = i + i; j <= 3000; j += i){
                isprime[j] = false;
            }
        }
    }
}
int main(){
    init();
    while(~scanf("%d%d",&n,&m)){
        memset(dp,0,sizeof(dp));
        for(int i = 0; i <= n; i++){
            ans[i] = 1;
        }
        for(int i = 0; i < num && prime[i] <= n; i++){
            double cnt = log(prime[i]*1.0);
            for(int j = n; j >= prime[i]; j--){
                for(int k = 1,p = prime[i]; p <= j; p *= prime[i],k++){
                    if(dp[j-p] + cnt * k > dp[j]){
                        dp[j] = dp[j-p] + cnt * k;
                        ans[j] = ans[j-p] * p % m;
                    }
                }
            }
        }
        printf("%d\n",ans[n]);
    }
    return 0;
}
dp-hdu-3092-Least common multiple 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3092 题目大意: 给一个数n,求一个划分a1,a2,...ak 使得ans=lcm(a1,a2,..,ak)最大,输出ans%m。 解题思路: 对于一个划分肯定是任意的i,j gcd(ai,aj)=1最优。如果gcd(ai,aj)>1 则最小公倍数肯定小些。 预处理所有的质数,转为话 阅读详情

相关推荐

Windows下用Docker部署RagFlow的5个常见错误及解决方法(附详细日志分析)

本文针对Windows系统下使用Docker部署RagFlow的常见难题,提供了详细的避坑指南。文章深度剖析了WSL2配置、端口冲突、文件权限、资源限制及网络通信这五个典型错误场景,并结合具体日志分析,给出了经过验证的解决方案,帮助开发者高效完成部署。

weixin_29233857的博客 178

最近公共祖先LCA问题

问题描述 求有根树的任意两个节点的最近公共祖先。 分析与解法 解答这个问题之前,咱们得先搞清楚到底什么是最近公共祖先。最近公共祖先简称LCA(Lowest Common Ancestor),所谓LCA,是当给定一个有根树T时,对于任意两个结点u、v,找到一个离根最远的结点x,使得x同时是u和v的祖先,x 便是u、v的最近公共祖先。(参见:http://en.wikipedia.o

Al_xin的专栏 2570

告别TwinCAT:手把手教你用IgH EtherCAT Master在LinuxCNC上搭建实时运动控制平台

本文详细介绍了如何利用IgH EtherCAT Master和LinuxCNC搭建开源实时运动控制平台,替代商业软件TwinCAT。通过分步指南,包括实时Linux环境配置、EtherCAT主站安装、LinuxCNC集成及多轴同步控制实现,帮助开发者构建高性能、低成本的工业自动化解决方案。

weixin_42641741的博客 401

最小公倍数(Least_Common_Multiple)

一、定义 几个数共有的倍数叫做这几个数的公倍数,其中除0以外最小的一个公倍数,叫做这几个数的最小公倍数。自然数a、b的最小公倍数可以记作[a、b],自然数a、b的最大公最小公倍数因数可以记作(a、b),当(a、b)=1时,[a、b]= a×b。 如果两个数是倍数关系,则它们的最小公倍数就是较大的数,相邻的两个自然数的最小公倍数是它们的乘积。 最小公倍数=两数的乘积/最大公约(因)数, 解题时...

无限迭代中...... 4174

Visual Studio 2022与Qt集成实战:解决Qt.props导入错误的完整指南

本文详细解析了在Visual Studio 2022中集成Qt开发时,如何解决因Qt.props文件导入失败导致的编译错误。文章从问题根源入手,深入剖析了Qt.props文件与QtMsBuild环境变量的关系,并提供了从检查文件存在性、配置环境变量到直接修改项目文件路径的完整排查与修复方案,帮助开发者快速恢复项目构建。

wdx01234567的博客 675

【CVPR 2025】低光增强HVI论文精读与源码复现---part1 论文网络精读

【CVPR 2025】本文参考论文HVI: A New Color Space for Low-light Image Enhancement part1 在文章中对论文核心网络与原理展开详细解释 part2 对论文公开代码的arch网络与其他核心部分展开详细解释

BOB_BOB_BOB_的博客 3258

最小公倍数(Least Common Multiple)

最小公倍数=两个数的乘积/两个数的最大公约数。 接上篇求最大公约数方法,最小公倍数的代码如下: public class LCM { //最小公倍数=两数乘积/最大公约数 public static int lcm(int m, int n){ return m*n/GCD.gcd(m,n); } public static void main(String[] args){

foreverbu的专栏 4808

ArcGIS基础:点要素分割线要素和提取线要素的交点

第一个实验:【点要素分割线要素】看下原始数据:下图所示,2个红点和一条绿线,用2个点去分割这条线。 找到【数据管理工具】,在找到【要素】,再找到【在点处分割线】,如下图所示。 输入线、点要素,然后在【搜索半径】里输入5米,查看一下结果。 查看结果发现,线段被分割了2段,我们查看一下原因。 发现第2个点与线有一段距离,肯定是大于5米的,所以分割没有成功。可以量测一下距离,重新输入搜索半径。 我们把搜索半径改为200米,勘察结果,被点分割了3段。 接下来使用另外一个工具【在折点处分割线】,如下所示。

yuanYW7556的博客 1万+

HDU - 3092 Least common multiple (数论+背包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3092点击打开链接Least common multipleTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1036    Accepted S...

xuejye的博客 616

别再折腾框架了!用华为应用市场官方渠道搞定GBOX,安全安装谷歌全家桶(鸿蒙HarmonyOS 3/4实测)

本文详细介绍了如何在鸿蒙系统上通过华为应用市场官方渠道安全安装GBOX,实现谷歌全家桶的无损使用。该方法避免了传统破解方式的安全风险,利用沙箱技术隔离运行环境,确保系统稳定性和数据安全。特别适合鸿蒙HarmonyOS 3/4用户安全使用谷歌生态应用。

weixin_29305313的博客 4760

利用SPSS实现逻辑回归,树模型,以及广义线性模型

本案例是IBM SPSS数据分析与挖掘实战案例精粹----第九章的学习记录 案例背景:分析出导致急救后迟发性颅脑损伤的主要影响因素,共有201项案例: 分析思路:先使用logistic回归模型进行影响因素筛选,然后利用分类树探索自变量中是否存在交互作用,最后利用广义线性模型过程拟合带交互项的Logistic回归模型 字段:性别,年龄,收缩压,舒张压,血小板,脑挫伤,中线位移,脑肿胀,入院意识,是否手术急救,其余急救措施,是否出现迟发性脑损伤; ...

hepan_defeng的博客 1万+

HDU - 3092 Least common multiple 解题报告(数论+完全背包)

目录题目描述思路分析完整代码 题目描述 题目:http://acm.hdu.edu.cn/showproblem.php?pid=3092 大概意思:给定一个数s和模m,将s分解为几个数相加的形式,求这几个加数的最小公倍数最大值%m的值。 思路分析 这道题我一开始是一道数论题,就想着:既然要最小公倍数的最大值,最大公倍数lcm=a*b/k(k=gcd(a,b)),那么,我们有限考虑的应该是k最小,...

nagisa2019的博客 304

基于传统算法的半导体晶圆缺陷检测原理及代码(二)

了解基于传统算法的半导体晶圆缺陷检测原理和方法,对于深入理解半导体制造工艺和质量控制具有重要意义。在半导体制造技术持续创新的浪潮中,基于传统算法的缺陷检测技术也将不断演进,为半导体产业的高质量发展提供坚实可靠的技术支撑,确保在芯片制造的每一个环节都能精准识别和管控缺陷,推动半导体产业迈向更高的发展水平。基于传统算法的半导体晶圆缺陷检测技术在半导体制造的长期发展历程中扮演了重要角色,凭借其成熟的技术体系、较快的检测速度和相对较低的成本,在各个工艺阶段为保障晶圆质量发挥了关键作用。

m0_44975814的博客 2219

【HDU - 3092】Least common multiple(数学+完全背包)

Partychen like to do mathematical problems. One day, when he was doing on a least common multiple(LCM) problem, he suddenly thought of a very interesting question: if given a number of S, and we divid...

__似水流年__的博客 457

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

HDU3092:Least common multiple(素数筛选+完全背包)

题意 给出\(n\)和\(m\),将\(n\)拆成任意个数,求它们的最大的\(lcm\) 分析 1.可以证明\(n=p1^{s1}*p2^{s2}*...*pn^{sn}\)时\(lcm\)最大(其中\(p1,p2...pn\)皆为素数) 证明 2.那么就可以转化为完全背包,模仿公式 \(f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k*c[i]&l...

anquan1533的博客 195

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

HDU - 3092 Least common multiple (数论+背包)

题意: 求把一个整数S拆成若干数a_i的和, 并且这些数(a_i)的最小公倍数最大。输出最小公倍数对M取模。 分析: 容易想到质数肯定是跟答案有关,那么肯定是01背包容量为S,使得总价值最大,总价值即为lcm,但是可能一个素数取多次,例如9,4*5是最优解,但是只可能取素数的幂次,因为这样才能保证集合的数都互质,取倍数不能保证这一点,那么在01背包的基础上进行操作就可以了,枚举每个质数的时候...

兜率工的博客 406

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

TOJ 5960:Least common multiple(分组背包)

描述 Partychen like to do mathematical problems. One day, when he was doing on a least common multiple(LCM) problem, he suddenly thought of a very interesting question: if given a number of S, and we d...

__1_1__的博客 269

HDU 3092 Least common multiple【完全背包】

#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> using namespace std; int vis[3005],num,p[3000],ans[3010]; double dp[3010]; void cpnl() // cpnl means creat prime number list { memset(vis,0,sizeof(vis)); num=0; for(

MartaYang的博客 524

Least common multiple HDU - 3092

http://acm.hdu.edu.cn/showproblem.php?pid=3092 看的题解 首先 拆出的数必须是素数的次幂 假如拆出了14这样的数 他在lcm中的贡献与拆出2和7是一样的 反而浪费了5个数 然后就是分组背包了 即x x^1x^2 x^3算一组 只能选其中一个 最后 不能在DP过程中取模 这样无法比较大小 可以想到取个对数 化为浮点加法 同时另开一数组记录答案 ...

sunyutian1998的博客 246

HDU 3092 Least common multiple

题目链接:Least common multiple   题意:给你两个数n和m,让你将n切割成多个数字,求如何切割使得得到的数字的最小公倍数最大,最后输出最大公倍数对m取模后的结果。   题解: 首先,最小公倍数的求解:lcm(a,b)=a*b/gcd(a,b)   所以,要使最小公倍数lcm最大,则必须要让最大公约数gcd最小。而当两个数互质时,其最大公约数为1,此时满足题目所需要求...

zvzdjvnai~的博客 417

hdu3092 Least common multiple (数学+完全背包)

题目链接:点击这里 题目大意: 给定一个整数 nnn ,将其拆分成一些数的和,求出这些数的最小公倍数的最大值模 mmm 的值 题目分析: 因为是将 nnn 进行拆分,并对拆分方案求最值,我们考虑背包建模,将 nnn 理解为背包容量,数字理解为物品 显然在这些数互质的时候,最小公倍数最大,所以物品就是一组组的素数的幂次,每次从一组中选出一个素数的幂次来进行更新答案(分组背包) 因为答案会很大,而取余之后又难以辨别状态间的大小关系,所以我们对 dpdpdp 数字直接整体取对数,然后进行状态转移,对于答案我们单独

羊驼的博客 191

hdu 3092 Least common multiple

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3092 题意:给了一个数把它分成若干个数的和的形式,求这若干个数的最小公倍数的最大值是多少 分析:gcd(a,b) = 1时lcm最大,所以目标是尽可能将这个数处理成全为素数的形式。先用线性素数筛出3000里的所有质数,然后枚举每个质数,尽可能将这个质数填到n中,此时就类似于完全背包,每一个大于等于...

zhlbjtu2016的博客 267

HDU 3092 Least common multiple(完全背包+思维)

题目链接 题目大意:给你一个数n,你要将它分成若干数字的和,使其的lcm最大,并且对p取模 思路:有一个很显然的性质:分成的若干个数字的必定互质。之后就是完全背包问题了。F[I]表示和为I的得到的最大lcm,F[I]=max(F[I-prime[j]*k]*k*prime[j]) 因为F[I]的值可能超过long long范围,我们就对其取一个log,记为数组DP【】 #include&...

fufck 302
上一篇: Cake ZOJ - 3537(判断凸包模板+最优三角剖分+区间dp详解)
下一篇: Sonya and Exhibition(简单思维题)
Guuuuuu老师儿
博客等级 码龄9年 259粉丝 718原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值