L. Clock Master
数论+分组背包
打表找一找规律就发现了,我们不过是求这一个数组的最小公倍数,想办法让其最大
然后我们运用分组背包的想法,肯定里面的数互素的情况下才好。
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int max_n = 31000;
int a[max_n];
double dp[3500][max_n];
bool used[max_n];
int tot=0;
double b[3500];
void init()
{
for (int i=2;i<max_n;++i)
{
if (used[i])continue;
for (int j=i+i;j<max_n;j+=i)
{
used[j]=1;
}
a[++tot]=i;
}
for (int i=1;i<=tot;++i)
{
b[i]=log(a[i]);
}
}
int main()
{
ios::sync_with_stdio(0);
init();
int n = 30000;
for (int i=1;i<=tot;++i)
{
for (int j=1;j<=n;++j)
{
dp[i][j]=dp[i-1][j];
int ex1=a[i];
double ex2=b[i];
while (j-ex1>=0)
{
dp[i][j]=max(dp[i][j],dp[i-1][j-ex1]+ex2);
ex1*=a[i];
ex2+=b[i];
}
}
}
int T;scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
printf("%0.12llf\n",dp[tot][n]);
}
}