ACM学习历程—HDU 3092 Least common multiple(数论 && 动态规划 && 大数)
Description
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.
题目大意是,将一个数拆成若干数的和,然后对这些若干数求最小公倍数。求最小公倍数的最大值。
首先假设对于一个数x,我已经拆成若干数了。
对于其中两个数a和b。如果这两个数有最大公约数k。
那么这两个数个最小公倍数为a*b/k。
但是如果是a和b/k,最小公倍数依旧为a*b/k。但是两数的和更小了。这样我就可以多加一个数b-b/k,可能会使最终结果更大。
所以得到的第一个结论是,我尽量保证两两数都是互素的。
接下来,我要证明,每个数都应该是p^t的形式,p为素数。
因为当a > 1 &&
b > 1时,
(a-1)(b-1) >= 1。
即ab >= a+b。
同理来两次得到abc >= ab+c
>= a+b+c
所以,如果一个数y = p^t1*q^t2*c。p和q均为素数,且(p, q) =
(p, c) = (q, c) = 1。
那么我把拆成p^t1和q^t2和c,这三个数的最小公倍数就是y。但是这三个数的和更小了,可以再加入一个数y-p^t-q^t-c,可能会使结果更大。
所以,最终结论x = 2^c1 + 3^c2 +
5^c3 + ...,底数为素数。
到这里做法就比较多了。
有一种做法是用直接用dfs暴力搜索。
枚举对于一个素数p,加上p^i。
dfs(int now, int sum, BigInteger val)
这里now表示枚举到第几个素数,sum表示当前情况的和是多少,val表示当前最小公倍数。
这样一开始传入s,到了第二层递归树,分别为0, 2, 4,
8…,
对于2下方的一层是2, 2+3, 2+9…
首先3000以内素数有430个左右。层数可能会达到430层,就算不是满枝,复杂度也很大。
既然这样,
于是考虑p[i]数组表示i拆分的最小公倍数的最大值。
那么p[i] = max(p[i-prime[k]^t] * prime[k]^t)。
就是对于i,枚举它由i-prime[k]^t加prime[k]^t构成。然后求最值,这样之前枚举过的素数得到的最值都被记忆化了。
复杂度是:s*primeNum*log(s) ->
总和s*素数个数*枚举次方数
最差情况:3000*430*log(3000)这个复杂度不是很大,所以直接用java大数,这题也能过,不过网上也有取对数来防止数据溢出的方法。
代码:
import java.math.BigInteger;
import java.util.Scanner; public class Main
{
boolean isprime[] = new boolean[3005];
int prime[] = new int[450];
int top;
BigInteger p[] = new BigInteger[3005];
boolean vis[] = new boolean[3005];
//埃氏筛法求素数
void isPrime()
{
for (int i = 0; i < 3005; ++i)
isprime[i] = true;
isprime[0] = isprime[1] = false;//初始化
for (int i = 2; i <= 3000; ++i)//筛法
{
if (isprime[i])
{
for (int j = i*i; j <= 3000; j += i)//上界太大可能会爆int
{
isprime[j] = false;
}
}
}
top = 0;
for (int i = 0; i <= 3000; ++i)
if (isprime[i])
prime[top++] = i;
} BigInteger dp(int s)
{
BigInteger ans = new BigInteger("1");
vis[0] = true;
for (int i = 1; i <= s; ++i)
vis[i] = false;
p[0] = new BigInteger("1");
for (int i = 0; i < top && prime[i] <= s; ++i)
{
for (int j = s; j >= prime[i]; --j)
{
for (int k = prime[i]; k <= j; k *= prime[i])
{
if (j-k < 0 || !vis[j-k])
continue;
if (!vis[j])
{
p[j] = p[j-k].multiply(new BigInteger(Integer.toString(k)));
vis[j] = true;
}
else
p[j] = p[j].max(p[j-k].multiply(new BigInteger(Integer.toString(k))));
}
}
}
for (int i = 1; i <= s; ++i)
if (vis[i])
ans = ans.max(p[i]);
return ans;
} public static void main(String args[])
{
Main qt = new Main();
qt.isPrime();
BigInteger ans;
int s, m;
Scanner input = new Scanner(System.in);
while (input.hasNext())
{
s = input.nextInt();
m = input.nextInt();
ans = qt.dp(s);
System.out.println(ans.mod(new BigInteger(Integer.toString(m))));
}
}
}
ACM学习历程—HDU 3092 Least common multiple(数论 && 动态规划 && 大数)的更多相关文章
- 背包系列练习及总结(hud 2602 && hdu 2844 Coins && hdu 2159 && poj 1170 Shopping Offers && hdu 3092 Least common multiple && poj 1015 Jury Compromise)
作为一个oier,以及大学acm党背包是必不可少的一部分.好久没做背包类动规了.久违地练习下-.- dd__engi的背包九讲:http://love-oriented.com/pack/ 鸣谢htt ...
- HDU 3092 Least common multiple 01背包
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3092 Least common multiple Time Limit: 2000/1000 MS ...
- ACM学习历程—HDU5407 CRB and Candies(数论)
Problem Description CRB has N different candies. He is going to eat K candies.He wonders how many co ...
- ACM学习历程—HDU 5512 Pagodas(数学)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5512 学习菊苣的博客,只粘链接,不粘题目描述了. 题目大意就是给了初始的集合{a, b},然后取集合里 ...
- ACM学习历程—HDU 5317 RGCDQ (数论)
Problem Description Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more an ...
- ACM学习历程—HDU 3915 Game(Nim博弈 && xor高斯消元)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3915 题目大意是给了n个堆,然后去掉一些堆,使得先手变成必败局势. 首先这是个Nim博弈,必败局势是所 ...
- ACM学习历程—HDU 5536 Chip Factory(xor && 字典树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5536 题目大意是给了一个序列,求(si+sj)^sk的最大值. 首先n有1000,暴力理论上是不行的. ...
- ACM学习历程—HDU 5534 Partial Tree(动态规划)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5534 题目大意是给了n个结点,让后让构成一个树,假设每个节点的度为r1, r2, ...rn,求f(x ...
- ACM学习历程—HDU 3949 XOR(xor高斯消元)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3949 题目大意是给n个数,然后随便取几个数求xor和,求第k小的.(重复不计算) 首先想把所有xor的 ...
随机推荐
- 【BZOJ2460】[BeiJing2011]元素 贪心+高斯消元求线性基
[BZOJ2460][BeiJing2011]元素 Description 相传,在远古时期,位于西方大陆的 Magic Land 上,人们已经掌握了用魔法矿石炼制法杖的技术.那时人们就认识到,一个法 ...
- 九度OJ 1352:和为S的两个数字 (查找)
时间限制:2 秒 内存限制:32 兆 特殊判题:否 提交:3160 解决:833 题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输 ...
- 九度OJ 1350:二叉树的深度 (二叉树)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1044 解决:614 题目描述: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长 ...
- 九度OJ 1199:找位置 (计数)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2083 解决:1010 题目描述: 对给定的一个字符串,找出有重复的字符,并给出其位置,如:abcaaAB12ab12 输出:a,1:a,4 ...
- win7旗舰版 安装IIS中出现的问题
最好先安装IIS成功了,再安装VS2010或者别的版本 1.hppt 错误500.19,-Internal server erroe,无法访问的请求野蛮,因为该页的相关配置数据无效,HTTP Erro ...
- web audio living
总结网页音频直播的方案和遇到的问题. 代码:(github,待整理) 结果: 使用opus音频编码,web audio api 播放,可以达到100ms以内延时,高质量,低流量的音频直播. 背景: V ...
- WebApp页面开发小结
一 背景 公司需要开发一个web页面,需要支持主流android和ios手机,采用web页面好处是一个页面,在不同平台之间都可以用,节省成本,基本html.js和css大家也都熟悉.但是对 ...
- pyspark
http://www.aboutyun.com/thread-18150-1-1.html
- 转 Hadoop傻瓜化:Datameer大数据收入翻三番
淘薛奎发布到 <数据极客> 06-28 16:04 随着分析正在成为企业IT的核心,昔日的BI- ETL-EDW分析范型已经完全落伍,不再适用.而力推“大数据傻瓜化”的Datameer ...
- golang 获取指定目录下的子文件列表
GO语言按照深度遍历文件 原创 2016年07月20日 09:45:19 标签: go语言 / 遍历 / string 1971 常规方法不使用pathfilepath包 go的filepath包 g ...