L - Clock Master Gym - 102798L
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了L - Clock Master Gym - 102798L相关的知识,希望对你有一定的参考价值。
L - Clock Master Gym - 102798L
题意:
给定一个数字n,令n=a1+a2+a3…求lcm(a1,a2,a3,…)的最大值,以loge(x)的形式输出
题解:
lcm要求尽可能大,我们就要保证a1,a2,a3…尽可能为质数或质数的整数次幂,对于n = p1n1 +p2n2+…
我们将每个素数的不同幂次划分为一组,每个组我们最多只能选一个(也可以不选),问在n范围内,所能选的p1 * p2 *…的最大值
这个看着像什么?
有N件物品和一个容量为V的背包。第i件物品的费用是w[i],价值是v[i]。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
没错就是分组背包,容量V就是n,每组的物品就是p1的整数次幂,价值就是所选p1的整数次幂去log(因为题目输出要求),费用就是p1的整数次幂
log(p1 * p2 * p3…) = log(p1)+log(p2)+…
所以直接累加lg[x]
预处理出所有答案
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e4 + 10;
const int mod = 1e9 + 7;
int pri[N], tot;
double dp[N], Log[N];
bool vis[N];
void init() {
memset(vis, 0, sizeof(vis));
vis[0] = vis[1] = 1;
tot = 0;
for(int i = 2; i < N; ++i) {
if(!vis[i]) {
pri[++tot] = i;
for(int j = i + i; j < N; j += i)
vis[j] = 1;
}
}
for(int i = 0; i < N; ++i) Log[i] = log(i);//首先预处理出log答案
for(int i = 1; i <= tot; ++i) {//对于tot个分组
for(int j = N - 1; j >= pri[i]; --j) {//容量
for(int k = pri[i]; k <= j; k *= pri[i])//枚举pri[i]的整数次幂
dp[j] = max(dp[j], dp[j - k] + Log[k]);
}
}
}
int main() {
init();
int t, n;
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
printf("%.9f\\n", dp[n]);
}
return 0;
}
以上是关于L - Clock Master Gym - 102798L的主要内容,如果未能解决你的问题,请参考以下文章
Codechef MGCHGYM Misha and Gym 容斥背包Splay
Straight Master Gym-101775J (思维+差分)
2020 China Collegiate Programming Contest, Weihai Site L. Clock Master(分组背包)