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]);
} 
posted @ 2018-08-20 13:39  BLUE_EYE  阅读(188)  评论(1编辑  收藏  举报