首页 > 代码库 > BZOJ 1263 整数划分(数学+高精度)

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;
}
View Code

 

BZOJ 1263 整数划分(数学+高精度)