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 则最小公倍数肯定小些。 预处理所有的质数,转为话 阅读详情

相关推荐

别怕,“卷积”其实很简单

首先给大家讲一个关于卷积的小故事:小明是杭州某互联网大厂的员工,每天996十分辛苦,但小明最近爱上了打台球,经常不在工位。这天,小明的主管让小明改一个需求,小明却到楼下找产品部小丽打台球去了,被主管发现,他非常气愤,扇了小明一巴掌(注意,这就是输入信号,脉冲)。于是小明脸上会渐渐地(贱贱地)鼓起来一个包,小明的脸就是一个系统,而鼓起来的包就是小明的脸对巴掌的响应。好,这样就和信号系统建立起来意义对应的联系。

Machine Learning with Tutors 3181

最近公共祖先LCA问题

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

Al_xin的专栏 2570

金蝶云星空应用开发初级考试题目汇总

摘要:本文为金蝶云星空应用开发初级考试题目汇总

2401_86113757的博客 3799

最小公倍数(Least_Common_Multiple)

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

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

vins-mono前端详解(2)——imu预积分

本篇文章详细讲解了vins-mono中imu预积分内容,包括复杂的公式推导。

weixin_44587828的博客 1192

CESM笔记——CESM1.0-CESM1.2.2-CESM2.1.3三个版本模式工作流对比

最近测试了CESM1.0,CESM1.2.2和CESM2.1.3三个版本,不同版本在workflow上有一些区别,来做点笔记。 CESM1.0 测试compset:B_2000,F_2000 workflow: 1. create_newcase -case ~/CESM/cesm1_0/script/B_2000 -compset B_2000 -res f19_g16 -mach tianhe 2. cd B_2000 (optional) env_mach_pes.xml ##修改核数,

砍柴姑娘Jourosy的博客 4942

最小公倍数(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

Zemax非序列模式新手入门:从零搭建一个抛物面反射镜系统(含灯丝光源与探测器设置)

本文详细介绍了如何在Zemax非序列模式下从零搭建抛物面反射镜系统,包括灯丝光源配置、反射镜建模和探测器设置等关键步骤。通过实战指南,帮助光学设计新手快速掌握非序列模式的应用技巧,特别适合处理复杂光线传播场景如反射镜系统和杂散光分析。

weixin_28717431的博客 436

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

电子纸价签实战:基于SSD1680的墨水屏驱动开发与优化

本文详细介绍了基于SSD1680驱动芯片的电子纸价签开发实战,涵盖硬件连接、驱动框架搭建、核心流程解析及性能优化。重点剖析了初始化配置、波形文件加载、图像数据写入与刷新触发等关键步骤,并提供了功耗优化、显示效果提升及代码健壮性等实用避坑指南,帮助开发者高效实现稳定低功耗的墨水屏驱动。

weixin_28278377的博客 227

【AlphaFold2】深入浅出,讲解Evoformer|学习笔记

本篇博客是围绕youtube德国博主Kilian Mandon()的《从头实现AlphaFold2:AlphaFold Decoded》的第五期视频讲解和note-book内容写成的笔记,加上了自己的理解和对相关概念的解释。上期我们讲解了AlphaFold2的特征提前的部分【AlphaFold2】Feature extraction:提取特征,为模型输入做准备|Datapipeline讲解。本期,我们将介绍AlphaFold2中最为庞大且最为重要的部分——Evoformer。

Yaoyao2024的博客 2013

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

vue3+vite - 解决报错error while updating dependencies:Error:EACCES:permission denied,mkdir ‘x‘(系统权限问题)

vue3,vite,报错,nuxt,权限,苹果mac系统,windows系统,vue3报错,vite报错,node,详细解决方法,教程,[vite] error while updating dependencies: Error:EACCES:permission denied,mkdir 'x',更新依赖项时发生[vite]错误:错误:EACCES:权限被拒绝,mkdir,苹果mac系统加了sudo还是不行报错,运行报错,启动项目,run dev,创建项目,初始化,依旧不行怎么办,保权限没有问题,换了n

✅ 精选推荐文章 5554

【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

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

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

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

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

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

兜率工的博客 406

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

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、付费专栏及课程。

余额充值