考虑不是划分成整数,而是划分成任意实数
设我们将n划分成了x个正实数之和
易知当这x个数相等时答案是最优的
那么每个数都是 nx ,答案是 (nx)x
设 y=(nx)x
则有 lny=x[lnn−lnx]
两侧求导可得 y′=(n/x)x∗(lnn−lnx−1)
当 x=ne 时y’取0 此时乘积最大
因此每个数要尽量靠近e才能使答案最大
现在考虑整数 离e最近的整数是3 因此要把n尽量分成3 不足的用2补齐 这样可以保证是最优的。
referring to: PoPoQQQ
所以可以得到以下结论:
如果n是3的倍数 那么将n划分成n/3个3是最优的
如果n是3的倍数+1 那么将n划分成(n-4)/3个3和两个2是最优的
如果n是3的倍数+2 那么将n划分成(n-2)/3个3和1个2是最优的
还撸了一遍python,发现老是PE。。。根本不会写啊。。。
#include<bits/stdc++.h>
#define lca long long
using namespace std;
int tot;
struct big{
int xx[5050];
int cnt;
big(int x=0)
{
memset(xx,0,sizeof(xx));
xx[1]=x;
cnt=1;
}
int & operator [] (int x)
{
return xx[x];
}
}ans(1);
big operator *= (big &a,big &b)
{
big z;
for(int i=1;i<=a.cnt;i++)
for(int j=1;j<=b.cnt;j++)
z[i+j-1]+=a[i]*b[j],z[i+j]+=z[i+j-1]/10,z[i+j-1]%=10;
z.cnt=a.cnt+b.cnt;
if(!z[z.cnt]) z.cnt--;
a=z;
}
int main()
{
int n;
scanf("%d",&n);
while(n>4)
{
big temp(3);
n-=3;
ans*=temp;
}
if(n==4)
{
big temp(4);
ans*=temp;
}
else if(n==3)
{
big temp(3);
ans*=temp;
}
else if(n==2)
{
big temp(2);
ans*=temp;
}
printf("%d\n",ans.cnt);
for(int i=ans.cnt;i;i--)
{
printf("%d",ans[i]);
tot++;
if(tot==100)
break;
}
}
PE 的py:
n=int(input())
sum=1
op=n%3
tim=(int)(n/3)
if op==0:
while tim>0:
tim-=1
sum*=3
if op==1:
tim-=1
while tim>0:
tim-=1
sum*=3
sum*=4
if op==2:
while tim>0:
tim-=1
sum*=2
sum*=2
temp=sum
num=0
basic=1
while temp>0:
num+=1
temp=temp//10
print('%d '%num)
if num<=100:
print(sum)
else:
temp=sum
cnt=0
basic=1
while cnt!=num-100:
cnt+=1
temp=(temp//10)
print('%d'%temp)