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 ti-tooth gear, then the i-th pointer will point to kmodti 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 (d1,d2,⋯,dn) is valid, if it can be written for some nonnegative integer k, where ti 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;
}