题意:给出一个数拆成若干个数的和,使这些数的lcm最大
分析:题意非常难懂,给了很多无关的概念干扰项,比赛时读了三遍才搞懂,赛场时一直再猜结论,一直卡了有俩小时吧。补题时知道是分组背包后很快就有思路了,想来还是对于dp不够熟悉,另外需要一提的是log(n)的复杂度很大,需要预处理否则会T
代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define mid (l+r>>1)
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int, double>pii;
typedef vector<int>vi;
struct tri {int a, b, c;};
const int N = 3e4 + 10;
const int inf = 0x3f3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
bool vis[N];
double dp[N],ln[N];
int main()
{
ios::sync_with_stdio(0), cin.tie(0);
// freopen("in.txt", "r", stdin);
for(int i=2;i<N;i++)ln[i]=log(i);
for(int i = 2; i < N; i++) if(!vis[i])
for(int j = i * i; j < N; j += i) vis[j] = 1;
for(int i = 2; i < N; i++) if(!vis[i])
for(int j = N - 1; j; j--)
for(int k = i; k < N; k *= i) if(k <= j)
dp[j] = max(dp[j], dp[j - k] + ln[k]);
int _; cin >> _;
while(_--)
{
int b; cin >> b;
cout << fixed << setprecision(9) << dp[b] << endl;
}
return 0;
}