P1018 乘積最大(高精度加/乘)
阿新 • • 發佈:2018-11-05
一道dp題目。比較好像的dp題目。
然而他需要高精度計算。
所以,他從我開始學oi,到現在。一直是60分的狀態。
今天正打算複習模板。也就有藉口解決了這道題目。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using std::max; using std::min; const int maxn=100; const long long Base=1e7; struct node { int L; long long m[maxn]; node(int a=-1) { L=a;memset(m,0,sizeof(m)); } void exact() { while(!m[L]&&L>-1) L--; return ; } void fill(char *A,int l,int r) { int len=(r-l+1)/7-((r-l+1)%7==0); L=len; /*for(int i=len;i>=0;i--) for(int j=i*7;j<=i*7+6&&l+j<=r;j++) m[len-i]=m[len-i]*10+A[l+j]-'0';*/ for(int i=r,tot=0;i>=0;i-=7,tot++) for(int j=min(6,i-l);j>=0&&i-j>=l;j--) m[tot]=m[tot]*10+A[i-j]-'0'; return ; } node operator + (const node &a)const { node res(max(L,a.L)+1); for(int i=0;i<=res.L;i++) { res.m[i]+=m[i]+a.m[i]; res.m[i+1]+=res.m[i]/Base; res.m[i]%=Base; } res.exact(); return res; } node operator * (const node &a)const { node res(L+a.L+1); for(int i=0;i<=L;i++) for(int j=0;j<=a.L;j++) { res.m[i+j]+=m[i]*a.m[j]; res.m[i+j+1]+=res.m[i+j]/Base; res.m[i+j]%=Base; } res.exact(); return res; } bool operator <(const node &a)const { if(L!=a.L) return L<a.L; for(int i=L;i>=0;i--) if(m[i]!=a.m[i]) return m[i]<a.m[i]; return true; } void print() { if(L==-1) { printf("0"); return ; } printf("%lld",m[L]); for(int i=L-1;i>=0;i--) printf("%07lld",m[i]); printf("\n"); return ; } }; node base[41][41]; node f[41][41]; node a,b,c; char data[50]; int main() { int s,k; scanf("%d%d",&s,&k); scanf("%s",data+1); /*for(long long i=2;i<=s;i++) for(long long j=i-1;j>0;j--) { a[j][i]=a[j][i-1]*10+a[i][i]; }*/ for(int i=1;i<=s;i++) for(int j=i;j<=s;j++) base[i][j].fill(data,i,j); for(int i=1;i<=s;i++) f[i][0]=base[1][i]; for(int k1=1;k1<=k;k1++) for(int i=k1;i<=s;i++) for(int j=k1;j<i;j++) f[i][k1]=max(f[i][k1],f[j][k1-1]*base[j+1][i]); f[s][k].print(); }