2020 CCPC (威海) - L Clock Master(分组背包)

链接: 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]);
    }
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值