BZOJ 1263 整数划分(数学+高精度)
Posted freeloop
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 1263 整数划分(数学+高精度)相关的知识,希望对你有一定的参考价值。
我们不妨考虑可以划分为实数的情况,设划分为x份实数,使得总乘积最大。
易得当每一份都相等时乘积最大。即 ans=(n/x)^x. 现在只需要求出这个函数取得最大值的时候x的取值了。
两边取对数,则有ln(ans)=x*ln(n/x). 再两边取导数。可得当x=n/e的时候,每份是e的时候,总乘积最大。
那么现在考虑为整数的情况,由于3最接近e,则尽量将n分成每份为3.
那么现在就可以得出,当n%3==0时,分成n/3份3.
当n%3==1时,分成n/3-1份3和一份4.
当n%3==2时,分成n/3份3和一份2.
再结合高精度乘法即可求出答案。
# include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector> # include <queue> # include <stack> # include <map> # include <set> # include <cmath> # include <algorithm> using namespace std; # define lowbit(x) ((x)&(-x)) # define pi 3.1415926535 # define eps 1e-9 # define MOD 100000007 # define INF 1000000000 # define mem(a,b) memset(a,b,sizeof(a)) # define FOR(i,a,n) for(int i=a; i<=n; ++i) # define FO(i,a,n) for(int i=a; i<n; ++i) # define bug puts("H"); # define lch p<<1,l,mid # define rch p<<1|1,mid+1,r # define mp make_pair # define pb push_back typedef pair<int,int> PII; typedef vector<int> VI; # pragma comment(linker, "/STACK:1024000000,1024000000") typedef long long LL; int Scan() { int res=0, flag=0; char ch; if((ch=getchar())==\'-\') flag=1; else if(ch>=\'0\'&&ch<=\'9\') res=ch-\'0\'; while((ch=getchar())>=\'0\'&&ch<=\'9\') res=res*10+(ch-\'0\'); return flag?-res:res; } void Out(int a) { if(a<0) {putchar(\'-\'); a=-a;} if(a>=10) Out(a/10); putchar(a%10+\'0\'); } const int N=5005; //Code begin... struct BigInt{ const static int mod=10000; const static int DLEN=4; int a[1500], len; BigInt(){mem(a,0); len=1;} BigInt(int v){ mem(a,0); len=0; do{a[len++]=v%mod; v/=mod;}while(v); } BigInt operator*(const BigInt &b)const{ BigInt res; FO(i,0,len) { int up=0; FO(j,0,b.len) { int temp=a[i]*b.a[j]+res.a[i+j]+up; res.a[i+j]=temp%mod; up=temp/mod; } if (up) res.a[i+b.len]=up; } res.len=len+b.len; while (res.a[res.len-1]==0&&res.len>1) res.len--; return res; } void output(){ if (len<=24) { printf("%d",a[len-1]); for (int i=len-2; i>=0; --i) printf("%04d",a[i]); putchar(\'\\n\'); } else { int x=a[len-1], res=0; while (x) res++, x/=10; printf("%d",a[len-1]); for (int i=len-2; i>len-2-(100-res)/4; --i) printf("%04d",a[i]); if ((100-res)%4) { int t=(100-res)%4, tmp=a[len-2-(100-res)/4]; FO(i,t,4) tmp/=10; if (t==1) printf("%d",tmp); else if (t==2) printf("%02d",tmp); else printf("%03d",tmp); } } } int cal_len(){ int x=a[len-1], res=0; while (x) res++, x/=10; return res+(len-1)*4; } }; BigInt ans; int main () { int n; scanf("%d",&n); ans=BigInt(1); while (n>=6) ans=ans*BigInt(3), n-=3; if (n==5) ans=ans*BigInt(6); else ans=ans*BigInt(n); printf("%d\\n",ans.cal_len()); ans.output(); return 0; }
以上是关于BZOJ 1263 整数划分(数学+高精度)的主要内容,如果未能解决你的问题,请参考以下文章