|
本帖最后由 倚窗倾听风吹雨 于 2018-10-2 15:49 编辑
打高精做法。毕竟noip不让用__int128,调了一个中午,难受。- #include<iostream>
- #include<cstring>
- #define FOR(i,a,b) for(int i=a;i<=b;i++)
- #define ROF(i,a,b) for(int i=a;i>=b;i--)
- using namespace std;
- const int M=100;
- int n,m,jz[M][M][M],f[M][M][M],er[M][M],ans[M],A[M],B[M],c[M];
- string s;
- inline void mul(int *a,int *b)
- {
- memset(c,0,sizeof(c));
- int ex;
- FOR(i,1,a[0])
- {
- ex=0;
- FOR(j,1,b[0])
- {
- c[i+j-1]+=(a[i]*b[j]+ex);
- ex=c[i+j-1]/10;
- c[i+j-1]%=10;
- }
- c[i+b[0]]=ex;
- }
- c[0]=a[0]+b[0];
- while(c[0]>1 && !c[c[0]])c[0]--;
- FOR(i,0,c[0])a[i]=c[i];
- return;
- }
- inline void add(int *a,int *b)
- {
- memset(c,0,sizeof(c));
- c[0]=max(a[0],b[0]);
- FOR(i,1,c[0])
- {
- c[i]+=a[i]+b[i];
- c[i+1]+=c[i]/10;
- c[i]%=10;
- }
- c[0]++;
- while(!c[c[0]] && c[0]>1)c[0]--;
- FOR(i,0,c[0])a[i]=c[i];
- return;
- }
- inline bool Max(int *a,int *b)
- {
- while(a[0]>0 && !a[a[0]])a[0]--;
- while(b[0]>0 && !b[b[0]])b[0]--;
- if(a[0]!=b[0])return a[0]>b[0];
- ROF(i,a[0],1)if(a[i]!=b[i])return a[i]>b[i];
- return true;
- }
- inline void print(int *a)
- {
- while(a[0]>1 && a[a[0]]==0)a[0]--;
- ROF(i,a[0],1)cout<<a[i];
- cout<<endl;
- }
- int main()
- {
- cin>>n>>m;
- FOR(i,1,n)FOR(j,1,m)
- {
- cin>>s;
- ROF(k,s.size()-1,0)
- jz[i][j][++jz[i][j][0]]=s[k]-'0';
- }
- er[0][0]=1;er[0][1]=1;
- FOR(i,1,m)
- {
- FOR(j,0,er[i-1][0])er[i][j]=er[i-1][j];
- add(er[i],er[i-1]);
- ///print(er[i]);
- }
- FOR(i,1,n)
- {
- memset(f,0,sizeof(f));
- FOR(j,1,m)
- {
- add(f[j][j],jz[i][j]);
- ///print(f[j][j]);
- mul(f[j][j],er[m]);
- ///print(f[j][j]);
- }
- FOR(l,1,m-1)
- for(int j=1,k=j+l;k<=m;j++,k++)
- {
- memset(A,0,sizeof(A));
- add(A,jz[i][j]);
- mul(A,er[m-l]);
- add(A,f[j+1][k]);
- memset(B,0,sizeof(B));
- add(B,jz[i][k]);
- mul(B,er[m-l]);
- add(B,f[j][k-1]);
- ///print(A);print(B);
- if(Max(A,B))FOR(o,0,A[0])f[j][k][o]=A[o];
- else FOR(o,0,B[0])f[j][k][o]=B[o];
- }
- ///print(f[1][m]);
- add(ans,f[1][m]);
- }
- print(ans);
- return 0;
- }
复制代码
|
|