BZOJ 1263 [SCOI2006]整數劃分 - 高精度乘法

考慮不是劃分成整數,而是劃分成任意實數
設我們將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=1
op=n%3
tim=(int)(n/3)
if op==0:
    while tim>0:
        tim-=1
        sum*=3
if op==1:
    tim-=1
    while tim>0:
        tim-=1
        sum*=3
    sum*=4
if op==2:
    while tim>0:
        tim-=1
        sum*=2
    sum*=2

temp=sum
num=0
basic=1
while temp>0:
    num+=1
    temp=temp//10
print('%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)

發佈了112 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章