分析
$f[][][M]$中的$M$是用来存储新得到的数的每个位上面的数是多少。
样例1加空格输出
1 2 2 1 4 8 8 4
结果可以发现,$f[][][M]$中第0位(个位)数字是4,第1位(十位)是8…
所以不需要$ vector<int\> $计算时先逆序再进行计算,可以直接进行运算。
所以比较直观理解,也就是y总的偷懒高精度 233
C++ 代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 210,M = 35,INF=0x3f3f3f3f;
int n;
LL f[N][N][M],w[N];
int cmp(LL a[],LL b[]) //判断a是否比b大
{
for(int i=M-1;i>=0;i--) //直接从高位进行比较,如果某一位a[i]>b[i],则说明a比b这个数大
{
if(a[i]>b[i]) return 1;
if(a[i]<b[i]) return -1;
}
return 0;
}
void add(LL a[],LL b[]) //直接从0位(个位)加,一直加到最高位M-1位为止
{
LL temp[M];
memset(temp,0,sizeof temp);
for(int i=0,t=0;i<M;i++)
{
t+=a[i]+b[i];
temp[i]=t%10;
t/=10;
}
memcpy(a,temp,sizeof temp);
}
void mul(LL a[],LL b) //从0位(个位)开始乘,一直乘到最高位M-1位
{
LL temp[M],t=0;
memset(temp,0,sizeof temp);
for(int i=0;i<M;i++)
{
t+=a[i]*b;
temp[i]=t%10;
t/=10;
}
memcpy(a,temp,sizeof temp);
}
void print(LL a[])
{
int k=M-1;
while(k && !a[k]) k--; //输出之前要将所有的前导0都去掉
for(int i=k;i>=0;i--)
cout<<a[i]<<" ";
cout<<endl;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>w[i];
LL temp[M];
for(int len=1;len<=n;len++)
{
for(int l=1;l+len-1<=n;l++)
{
int r=l+len-1;
if(len<3){
continue;
}
else{
f[l][r][M-1]=1;
for(int k=l;k<r;k++)
{
memset(temp,0,sizeof temp);
temp[0]=w[l]; //此时temp[0]=w[l],其余位数都是0,第0位表示w[l]这个数字
//print(temp);
mul(temp,w[k]); //乘过之后就是每一位数字对应到了数组M[]中的每位上了
//print(temp);
mul(temp,w[r]);
add(temp,f[l][k]); //由于temp为一维数组类型,f[l][k]也是一维数组(M[]是一维数组),可以直接加
add(temp,f[k][r]); //同理
if(cmp(f[l][r],temp)>0)
{
memcpy(f[l][r],temp,sizeof temp);
}
}
}
}
}
print(f[1][n]);
return 0;
}
为什么要判断a比b大,还有cmp函数的参数不是一维数组吗,调用的时候把f[l][r]传进去也可以吗?