链接: L Clock Master
题意:
题目说了一大堆 , 其实简化一下就是 给你一个 n ,把 n 分解成几个数相加 ,使这几个数的 lcm 最大。
思路:
要使 lcm 最大 ,选的几个数肯定是互质的 ,不然就会产生无用的贡献,所以把每个质数和它的幂次分成一组(每组选一个),然后跑分组背包,求最大贡献就好了。质数 加上它的幂次好像就 3000 来个,最后差不多 1e7 , 一开始 T 了,然后把 log 预处理一下就过了。
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
const int maxn = 3e4 + 7;
int isp[maxn] , pri[maxn];
int k;
double dp[maxn],lg[maxn];
vector< int > vec[maxn];
void sieve(){
for(int i = 2; i <= 3e4; i ++){
if(isp[i] == 0){
pri[k++] = i;
for(int j = i; j <= 3e4; j += i){
isp[j] = 1;
}
}
}
}
int main (){
sieve();
for(int i = 1; i <= 3e4; i ++) lg[i] = log(i);
for(int i = 0; i < k; i ++){
int temp = pri[i];
while(temp <= 3e4){
vec[i].push_back(temp);
temp *= pri[i];
}
}
for(int i = 0; i < k; i ++){
for(int j = 3e4; j >= 0; j --){
for(auto k: vec[i]){
if(j >= k)
dp[j] = max(dp[j] , dp[j - k] + lg[k]);
}
}
}
int T , n;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
printf ("%.9f\n",dp[n]);
}
}