BZOJ1263 (求导后高精)
原题 将一个正整数分成若干份,使其乘积最大
显然即求\((\dfrac{a}{x})^x\)的最大值
y=\((\dfrac{a}{x})^x\) 两边取对数
\(lny=x(lna-lnx)=xlna-xlnx\) 求一下导
是\(y'/y=lna-lnx-1=ln\dfrac{a}{e}-lnx\)
所以\(y'=(\dfrac{a}{x})^x*(ln\dfrac{a}{e}-lnx)\)
当x取到\(\dfrac{a}{x}\)时为0,此时\(\dfrac{a}{x}=e\)
由于我们是取整数 所以取与e最接近的3为底
当这个正整数是3的倍数的时候 取\(3^n\)次即可
当模3余1时 最后一个非3的数取4,因为\(4>3*1\)
当模3余2时 最后一个非3的数取4 因为\(2*3>5\)
最后写一下高精就好了
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct bigint{
int s[8000],l;
bigint(){memset(s,0,sizeof(s));l=0;}
bigint operator * (const bigint& b){
bigint all;
for(int i=0;i<l;i++)
for(int j=0;j<b.l;j++){
all.s[i+j]+=s[i]*b.s[j];
all.s[i+j+1]+=all.s[i+j]/10;
all.s[i+j]%=10;
}int len=l+b.l+2;
while(!all.s[len]) len--;all.l=len+1;
return all;
}
};
bigint qpow(bigint x,int k){
bigint w;w.l=1,w.s[0]=1;
for(int i=k;i;i>>=1,x=x*x)
if(i&1) w=w*x;
return w;
}
int main(){
int n;scanf("%d",&n);bigint w;
bigint t;t.s[0]=2,t.l=1;bigint three;three.s[0]=3,three.l=1;
if(n%3==1) w=qpow(three,n/3-1)*t*t;
else if(n%3==2) w=qpow(three,n/3)*t;
else w=qpow(three,n/3);
printf("%d\n",w.l);
for(int i=w.l-1;i>=max(0,w.l-100);i--) printf("%d",w.s[i]);
}