题意

$\DeclareMathOperator{\lcm}{lcm}$选 $k$ ($k\le 10$) 个 $1$ 到 $n$($n\le 10^9$)之间的整数(可以相同),使得 $\lcm(a_1, \dots, a_k)$ 最大。

题解

这是 hihoCoder 挑战赛 #6 的 B 题,CLJ(WJMZBMR) 出的。CLJ 的题解:

首先我们注意到,如果你选择了两个不互质的 $a, b$,那么不妨把 $a$ 换成 $a/(a,b)$。显然 LCM 还是不变的。

这意味着存在一组最优解使得所有选择的数都两两互质。

那么我们不妨使用暴搜,首先我们注意到我们至少可以选择比 $n$ 小的最大的 $k$ 个质数来当做初始解。

然后我们从大到小枚举是否使用,搜到 $x$ 时,假如当前最优解是 $ans$, 当前 LCM 是 $w$, 如果还能选择 $t$ 个, 假如 $wx^t \le ans$,那么显然已经无法得出更优的解了,就可以剪枝了。

首先需要指出,上面题解中

如果你选择了两个不互质的数 $a, b$,那么不妨把 $a$ 换成 $a/(a,b)$ 。显然 LCM 还是不变的。

这个结论是错误的,很容易举出反例:$a=4, b=2$,可能是作者笔误。不过,对于不互质的两个数 $a,b$ ,确实存在两个互质的数 $a',b'$ ($a'\le a, b'\le b$),使得 $\lcm(a',b') = \lcm(a,b)$。

写出 $a, b$ 两数的质因子展开式,设

$$

\begin{align}

a = p_1^{i_1} p_2^{i_2}\dots p_n^{i_n} \notag\

b = p_1^{j_1} p_2^{j_2}\dots p_n^{j_n} \notag

\end{align}

$$

在 $a$,$b$ 展开式中,只保留幂次较大的项便得到了 $a'$, $b'$。

至此,我遇到了一个困难:如何求比 $n$($n\le 10^9$)小的最大的 $k$($k\le 10$)个素数?

当然,求出 $k$ 个最大的素数并非我们的最终目的,这样做只是为了得到一个较大的初始解,求出不满 $k$ 个最大的素数也无妨,从而我们可以暴力判断后若干(比如 100)个数。另外,应当能看出初始解是否取一个较大的值,对程序运行时间影响并不大,将其取为 $n$ 甚至 $0$ 也可以。

复杂度

??从递归深度开始考虑??(大误,递归深度最大即为 $k$ 啊!!!我真是沙茶)

Implementation

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. vector<int> a;
  4. long long res;
  5. long double product;
  6. const int mod = 1e9 + 7;
  7. int n, k;
  8. void dfs(int x, long double cur_prod){
  9. if(a.size() == k || x == 1){
  10. // product = cur_rod;
  11. res = 1;
  12. product = cur_prod;
  13. for(auto i: a){
  14. // product *= i;
  15. res *= i, res %= mod;
  16. }
  17. return;
  18. }
  19. if(cur_prod * pow((long double)x, k - a.size()) <= product)
  20. return; // 剪枝
  21. bool flag = true;
  22. for(auto i: a)
  23. if(__gcd(x, i) != 1){
  24. flag = false;
  25. break;
  26. }
  27. if(flag){
  28. a.push_back(x);
  29. dfs(x-1, cur_prod * x);
  30. a.pop_back();
  31. }
  32. dfs(x-1, cur_prod);
  33. }
  34. int main(){
  35. // int n, k;
  36. cin >> n >> k;
  37. // product = n == 1 ? n : n * (n - 1);
  38. product = n;
  39. res = n;
  40. dfs(n, 1);
  41. cout << res << endl;
  42. return 0;
  43. }

上面代码中的 dfs() 还有一种写法:

  1. void dfs(int x, long double cur_prod){
  2. if(a.size() == k || x == 1){
  3. res = 1;
  4. product = cur_prod;
  5. for(auto i: a){
  6. res *= i, res %= mod;
  7. }
  8. return;
  9. }
  10. for(int i = x; ; i--){
  11. bool flag = true;
  12. for(auto j: a){
  13. if(__gcd(i, j) != 1){
  14. flag = false;
  15. break;
  16. }
  17. }
  18. if(!flag) continue;
  19. if(cur_prod * pow((long double)i, k - a.size()) <= product)
  20. break;
  21. a.push_back(i);
  22. dfs(i, cur_prod * i);
  23. a.pop_back();
  24. }
  25. }

hihoCoder #1072 辅导的更多相关文章

  1. hihocoder -1121-二分图的判定

    hihocoder -1121-二分图的判定 1121 : 二分图一•二分图判定 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 大家好,我是小Hi和小Ho的小伙伴Net ...

  2. Hihocoder 太阁最新面经算法竞赛18

    Hihocoder 太阁最新面经算法竞赛18 source: https://hihocoder.com/contest/hihointerview27/problems 题目1 : Big Plus ...

  3. hihoCoder太阁最新面经算法竞赛15

    hihoCoder太阁最新面经算法竞赛15 Link: http://hihocoder.com/contest/hihointerview24 题目1 : Boarding Passes 时间限制: ...

  4. 【hihoCoder 1454】【hiho挑战赛25】【坑】Rikka with Tree II

    http://hihocoder.com/problemset/problem/1454 调了好长时间,谜之WA... 等我以后学好dp再来看为什么吧,先弃坑(╯‵□′)╯︵┻━┻ #include& ...

  5. 【hihocoder#1413】Rikka with String 后缀自动机 + 差分

    搞了一上午+接近一下午这个题,然后被屠了个稀烂,默默仰慕一晚上学会SAM的以及半天4道SAM的hxy大爷. 题目链接:http://hihocoder.com/problemset/problem/1 ...

  6. 【hihoCoder】1148:2月29日

    问题:http://hihocoder.com/problemset/problem/1148 给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期). 思路: 1. 将问题转换成求两个日 ...

  7. 【hihoCoder】1288 : Font Size

    题目:http://hihocoder.com/problemset/problem/1288 手机屏幕大小为 W(宽) * H(长),一篇文章有N段,每段有ai个字,要求使得该文章占用的页数不超过P ...

  8. 【hihoCoder】1082: 然而沼跃鱼早就看穿了一切

      题目:http://hihocoder.com/problemset/problem/1082 输入一个字符串,将其中特定的单词替换成另一个单词   代码注意点: 1. getline(istre ...

  9. 【hihoCoder】1121:二分图一·二分图判定

      题目   http://hihocoder.com/problemset/problem/1121 无向图上有N个点,两两之间可以有连线,共有M条连线. 如果对所有点进行涂色(白/黑),判定是否存 ...

随机推荐

  1. IT界程序员几大恶习能立即让你变穷,你有吗?

    IT软件开发,确实是各行业中薪水排名靠前的职业,月薪在八千以上的Java程序员多不胜数,但是不知有没有以下几种恶习?如果粘上一种,哪怕你薪水几万,估计最后也是囊中羞涩:综上所述列举以下几点,亲们自己对 ...

  2. UVA 110020 Efficient Solutions (STL)

    把一个人看出一个二维的点,优势的点就是就原点为左下角,这个点为右上角的矩形,包含除了右上角以外边界,其他任意地方不存在点. 那么所有有优势的点将会形成一条下凹的曲线. 因为可能有重点,用multise ...

  3. UVA439 knightMoves (A*启发搜索)

    第一个A*,纪念下. A*要保证最短路一定要估价函数小于等于实际值,越接近越好 估价函数取Manhattan距离除以二. //Rey #include<cstdio> #include&l ...

  4. CF Gym 100637F The Pool for Lucky Ones

    题意:给你一串非负整数,可以将一个非零数减1,加到相邻的数字上,要使其中所有最大数字的和最小. 题解:模拟可以过.也可以分析,可以要减少最大数字和,如果最大数字出现大于等于3次,可以把最大数字加一,或 ...

  5. python_97_类的继承2

    # 经典类与新式类差别主要体现在多继承上 #多继承是从左到有 class People():#经典类 #class People(object):#新式类 def __init__(self,name ...

  6. kubernetes-深入理解pod对象(七)

    Pod中如何管理多个容器 Pod中可以同时运行多个进程(作为容器运行)协同工作.同一个Pod中的容器会自动的分配到同一个 node 上.同一个Pod中的容器共享资源.网络环境和依赖,它们总是被同时调度 ...

  7. Stream great concerts wherever you are

    This time of year, we take stock of what we're thankful for — and above all else, we’re thankful for ...

  8. 转 Anaconda启动卡死的解决方案

    https://blog.csdn.net/meng_zhi_xiang/article/details/83651676

  9. Centos7离线部署kubernetes 1.13集群记录

    一.说明 本篇主要参考kubernetes中文社区的一篇部署文章(CentOS 使用二进制部署 Kubernetes 1.13集群),并做了更详细的记录以备用. 二.部署环境 1.kubernetes ...

  10. mysql 主从数据校验

    使用工具pt-table-checksum: /usr/bin/pt-table-checksum --user=root --password='mysqlpass' --host=127.0.0. ...