题意:
对于一个给定的n×m 的矩阵,矩阵中的每个元素 $a_{i,j}$ 均为非负整数。
每次从每行首或尾去一个数字
每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分 = 被取走的元素值×$2^i$ ,
其中 i 表示第 i 次取数(从 1 开始编号);
求出取数后的最大得分。
区间DP,以f[i][j]代表当前行取完剩下i到j的得分
那么若取头: f[i][j]=f[i+1][j]+num[i]*base[m-(j-i+1)];
若取尾: f[i][j]=f[i][j-1]+num[j]*base[m-(j-i+1)];
其中,base[i]代表2的i次方,可以预处理出来
每行ans+=f[i][j];
ans即为答案
然而我用贪心,每次取头或尾小的(大的留后面,有$2^i$更大,使得分更多
很明显是错的,a了2个点,因为较小数的旁边可以挨着一个很大的数,(极端)
要用高精!!
#include<cstdio> #include<iostream> #include<cstring> using namespace std; #define olinr return #define love_nmr 0 struct stat { int saf[105]; int len; stat() { memset(saf,0,sizeof saf); len=0; } int &operator [] (int a) { olinr saf[a]; } friend bool operator < (const stat &a,const stat &b) { if(a.len<b.len) olinr true; if(a.len>b.len) olinr false; for(int i=a.len;i>=1;i--) { if(a.saf[i]<b.saf[i]) olinr true; if(a.saf[i]>b.saf[i]) olinr false; } olinr true; } friend stat operator * (const stat &a,const stat &b) { stat c; c.len=a.len+b.len+2; for(int i=1;i<=a.len;i++) for(int j=1;j<=b.len;j++) { c.saf[i+j-1]+=a.saf[i]*b.saf[j]; c.saf[i+j]+=c.saf[i+j-1]/10; c.saf[i+j-1]%=10; } while(c.len>1&&c.saf[c.len]==0) c.len--; olinr c; } friend stat operator + (const stat &a,const stat &b) { stat c; c.len=max(a.len,b.len)+2; int x=0; for(int i=1;i<=c.len;i++) { c.saf[i]=a.saf[i]+b.saf[i]+x; x=c.saf[i]/10; c.saf[i]%=10; } while(c.len>1&&c.saf[c.len]==0) c.len--; olinr c; } void out() { for(int i=len;i>=1;i--) cout<<saf[i]; } }; struct node { int head; int tail; stat xl[100]; stat &operator [] (int a) { olinr xl[a]; } stat front() { olinr xl[head]; } stat back() { olinr xl[tail]; } void popfront() { head++; } void popback() { tail--; } }ju[100]; stat base[150]; stat two; stat f[100][100]; int n,m; stat ans; int main() { ios::sync_with_stdio(false); cin>>n>>m; two.len=1; two[1]=2; base[0].len=1; base[0][1]=1; for(int i=1;i<=100;i++) base[i]=base[i-1]*two; for(int i=1;i<=n;i++) { ju[i].head=1; ju[i].tail=m; for(int s,j=1;j<=m;j++) { cin>>s; while(s) { ju[i][j][++ju[i][j].len]=s%10; s/=10; } } } ans.len=1; ans[1]=0; for(int iq=1;iq<=n;iq++) { memset(f,0,sizeof f); for(int l=0;l<m;l++) for(int i=1;i+l<=m;i++) { int j=i+l; int pos=m-l; f[i][j]=max(f[i+1][j]+ju[iq][i]*base[pos],f[i][j-1]+ju[iq][j]*base[pos]); } ans=ans+f[1][m]; } ans.out(); olinr love_nmr; }