BZOJ 1263 [SCOI2006]整数划分

来源:互联网 发布:生物多样性数据库 编辑:程序博客网 时间:2024/06/05 22:55

考虑不是划分成整数,而是划分成任意实数
设我们将n划分成了x个正实数之和
易知当这x个数相等时答案是最优的
那么每个数都是nx,答案是(nx)x
y=(nx)x
则有lny=x[lnnlnx]
两侧求导可得y=(n/x)x(lnnlnx1)
x=ne时y’取0 此时乘积最大
因此每个数要尽量靠近e才能使答案最大
现在考虑整数 离e最近的整数是3 因此要把n尽量分成3 不足的用2补齐 这样可以保证是最优的。
referring to: PoPoQQQ

所以可以得到以下结论:

如果n是3的倍数 那么将n划分成n/3个3是最优的
如果n是3的倍数+1 那么将n划分成(n-4)/3个3和两个2是最优的
如果n是3的倍数+2 那么将n划分成(n-2)/3个3和1个2是最优的

还撸了一遍python,发现老是PE。。。根本不会写啊。。。

#include<bits/stdc++.h>#define lca long long using namespace std;int tot;struct big{   int xx[5050];   int cnt;   big(int x=0)   {      memset(xx,0,sizeof(xx));      xx[1]=x;      cnt=1;   }   int & operator [] (int x)   {      return xx[x];   }}ans(1);big operator *= (big &a,big &b){   big z;   for(int i=1;i<=a.cnt;i++)     for(int j=1;j<=b.cnt;j++)      z[i+j-1]+=a[i]*b[j],z[i+j]+=z[i+j-1]/10,z[i+j-1]%=10;   z.cnt=a.cnt+b.cnt;   if(!z[z.cnt]) z.cnt--;   a=z;}int main(){    int n;    scanf("%d",&n);    while(n>4)    {       big temp(3);       n-=3;       ans*=temp;    }    if(n==4)     {     big temp(4);     ans*=temp;    }    else if(n==3)     {     big temp(3);     ans*=temp;    }    else if(n==2)    {     big temp(2);     ans*=temp;    }    printf("%d\n",ans.cnt);    for(int i=ans.cnt;i;i--)    {       printf("%d",ans[i]);       tot++;       if(tot==100)        break;    }} 

PE 的py:

n=int(input())sum=1op=n%3tim=(int)(n/3)if op==0:    while tim>0:        tim-=1        sum*=3if op==1:    tim-=1    while tim>0:        tim-=1        sum*=3    sum*=4if op==2:    while tim>0:        tim-=1        sum*=2    sum*=2temp=sumnum=0basic=1while temp>0:    num+=1    temp=temp//10print('%d '%num)if num<=100:    print(sum)else:    temp=sum    cnt=0    basic=1    while cnt!=num-100:        cnt+=1        temp=(temp//10)    print('%d'%temp)
原创粉丝点击