【codevs1166】矩阵取数问题
这个题状态转移方程挺好想的,就是难写,就是难写!权当练习高精板子了
#include<algorithm> #include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int mn=80+5; int m,n,a[mn]; const int po=4;//压4位 const int ba=10000; const int ml=15; struct in { int a[ml]; in() { memset(a,0,sizeof(a)); } in operator + (const in &b) { in c; c.a[0]=max(a[0],b.a[0]); for(int i=1;i<=c.a[0];i++) { c.a[i]+=a[i]+b.a[i]; c.a[i+1]+=c.a[i]/ba; c.a[i]=c.a[i]%ba; } if(c.a[c.a[0]+1]) c.a[0]++; return c; } in operator + (const int &b) { a[1]+=b; int i=1; while(a[i]>=ba) { a[i+1]+=a[i]/ba; a[i]=a[i]%ba; i++; } if(a[a[0]+1]) a[0]++; return *this; } in operator = (int b) { a[0]=0; while(b) { a[0]++; a[a[0]]=b%ba; b/=ba; } return *this; } bool operator < (const in &b)const { if(a[0]<b.a[0]) return true; if(a[0]>b.a[0]) return false; for(int i=a[0];i>0;--i) { if(a[i]!=b.a[i]) return a[i]<b.a[i]; } return false; } void print() { printf("%d",a[a[0]]); for(int i=a[0]-1;i>0;--i) printf("%0*d",po,a[i]);//这句话意思是保证输出4位数,不够用0来凑 printf("\n"); } }ans,dp[mn][mn]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) scanf("%d",&a[j]); for(int j=1;j<=m;j++) dp[j][j]=a[j]; for(int j=1;j<=m-1;j++) for(int k=1;k<=m-j;k++) { int l=k+j; dp[k][l]=max(dp[k+1][l]+dp[k+1][l]+a[k],dp[k][l-1]+dp[k][l-1]+a[l]);//模拟取数的逆操作放数,之前那的答案要*2 }//dp[i][j]表示从i到j取数的答案 ans=ans+dp[1][m];//之前相当于从2^0取到2^m-1,所以要加两次 ans=ans+dp[1][m]; } ans.print(); }