2020ccpc威海 L Clock Master(数论 + 分组背包)

L Clock Master

With the rapid development of society, the demand for high-precision clocks is constantly rising. Recently, the China Clock Production Company is developing a new type of clock, which can represent a wide range of times.

The novel clock displays the current time in an unusual fashion. The clock consists of several pointers, each controlled by a gear. All gears rotate synchronously -- one tooth per period. However, the numbers of teeth of the gears may differ. If a gear has t teeth, then the corresponding pointer can point to t different directions, denoted 0,1,2,⋯,t−1, respectively, where 0 is the initial direction. Furthermore, if a clock is equipped with npointers, the i-th of which is controlled by a t​i​​-tooth gear, then the i-th pointer will point to kmodt​i​​ after kperiods of time.

The price for a t-tooth gear is t yuan. Given a total budget of b yuan, you need to design a combination of gears, such that the number of valid combinations of directions of pointers is maximized, and the total cost on gears does not exceed the budget. A combination of directions (d​1​​,d​2​​,⋯,d​n​​) is valid, if it can be written for some nonnegative integer k, where t​i​​ is the number of teeth of the i-th gear. Since the answer may be too large, output the answer in natural logarithm (logarithm with base e=2.718281828⋯).

Input Specification:

The first line of input is a single integer T (1≤T≤30000), indicating the number of test cases. Each test case is a single line of an integer b (1≤b≤30000), denoting the total budget.

Output Specification:

For each test case, print the natural logarithm, within an absolute or relative error of no more than 10​−6​​, of the maximum number of valid combinations, in a single line.

Sample Input 1:

3
2
7
10

Sample Output:

0.693147181
2.484906650
3.401197382

Notes:

For the second sample data, a 3-tooth gear along with a 4-tooth gear may yield 12 different combinations of directions, with total cost exactly being 7. So you should print the value of ln12, which is approximately 2.484906650.

题意:把 n 拆分为若干数的和,使得这些数的 lcm 最大,输出 log(lcm)

思路:使lcm最大也就是任意两个数之间尽量互素,考虑分组背包,一个素数的不同幂次划分为一组,问题即转化为了在每组只能选取一个数,求乘积最大值(不同组中的数是不同素数的幂次,一定互素,lcm即乘积)

坑点:会爆long long ,所以直接用double数组记录log值,提前打表

double最大值 1.7e308(tql

#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);
    for(int i = 1; i <= tot; ++i) {
        for(int j = N - 1; j >= pri[i]; --j) {
            for(int k = pri[i]; k <= j; k *= 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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43871207/article/details/109356151
今日推荐