2020CCPC Weihai Site L.Clock Mater 數論,分組揹包
阿新 • • 發佈:2020-10-28
2020CCPC Weihai Site L.Clock Mater 數論,揹包
題意
抽象出來就是給定\(n\),構造出最大的\(LCM(x_1 * x_2 *x_3....)\)且\(x_1 + x_2 + x_3 ... = n\)
\[1\leq T \leq 30000\\ 1\leq b \leq 30000 \]對答案輸出用\(ln(ans)\)
分析
考慮最後加起來的\(x\),肯定希望這些數互質,這樣就要求每個數唯一分解後形如\(p^\alpha\)
由於題給的範圍比較小,所以我們希望能列舉所有指數的情況,這個時候就用分組揹包即可
價值即\(log(x)\)
複雜度\(O(n^2logn)\)
注意點:計算每個數的對數有太多不必要的時間,可以預處理出\(ln\)
賽時沒做出這題,實在是不應該
程式碼
const int maxn = 1e5 + 5; int cnt; int prime[maxn]; int vis[maxn]; void euler_sieve() { cnt = 0; for (int i = 2; i <= maxn; i++) { if (!vis[i]) { prime[++cnt] = i; } for (int j = 1; j <= cnt; j++) { if (i * prime[j] > maxn) break; vis[i * prime[j]] = 1; if (i % prime[j] == 0) break; } } } double dp[30010]; double lg[30010]; const int M = 30010; void init() { for (int i = 0; i < M; i++) lg[i] = log(i); for (int i = 1; i <= cnt; i++) for (int j = M - 1; j >= prime[i]; j--) for (int k = prime[i]; k <= j; k *= prime[i]) dp[j] = max(dp[j], dp[j - k] + lg[k]); } void solve() { int n = rd(); printf("%.10f\n", dp[n]); } int main() { euler_sieve(); init(); int T = rd(); while (T--) solve(); }