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]);
} 

猜你喜欢

转载自www.cnblogs.com/BLUE-EYE/p/9505039.html
今日推荐