题意:给定n,用一些数加起来凑成n,使得这些数的最小公倍数最大,求最大的最小公倍数的自然对数。
思路:凑的这些数一定都是互素的,否则有浪费。那么【2,4,8,16…】【3,9,27…】【5…】【7…】求一个分组背包,就解决了。
#include<bits/stdc++.h>
using namespace std;
const int maxn=30000+10;
const int INF=0x3f3f3f3f;
int T,n,prime[maxn];
double dp[3300][maxn];
bool isprime(int n)
{
int m=sqrt(n+0.5);
for(int i=2;i<=m;i++)if(n%i==0)return false;
return true;
}
int main()
{
//freopen("input.in","r",stdin);
for(int i=2;i<maxn;i++)prime[i]=isprime(i);
for(int i=0;i<maxn;i++)dp[0][i]=1;
int cnt=0;
for(int i=2;i<maxn;i++)if(prime[i])
{
++cnt;
for(int j=0;j<maxn;j++)
{
int k=i;
dp[cnt][j]=dp[cnt-1][j];
while(k<maxn&&j-k>=0)dp[cnt][j]=max(dp[cnt][j],dp[cnt-1][j-k]*k),k*=i;
}
}
cin>>T;
while(T--)
{
cin>>n;
printf("%.8f\n",log(dp[cnt][n]));
}
return 0;
}