矩陣取數遊戲sol
阿新 • • 發佈:2020-07-25
- 容易發現每一行是獨立的,分別dp
- 設\(f(i,j,k)\)表示當前行,取到第i輪時,前面取了j個數,後面取了k個數,最大得分
#include<bits/stdc++.h> #define fi first #define se second #define pb push_back #define mp make_pair #define SZ(x) ((int)x.size()) #define ALL(x) x.begin(),x.end() #define U(i,u) for(register int i=head[u];i;i=nxt[i]) #define rep(i,a,b) for(register int i=(a);i<=(b);++i) #define per(i,a,b) for(register int i=(a);i>=(b);--i) using namespace std; typedef __int128 lll; typedef long double ld; typedef long long ll; typedef unsigned int ui; typedef pair<int,int> PII; typedef vector<int> VI; template<class T> inline void read(T &x){ x=0;char c=getchar();int f=1; while(!isdigit(c)){if(c=='-')f=-1;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=f; } template<class T> inline void cmin(T &x, T y){x=x<y?x:y;} template<class T> inline void cmax(T &x, T y){x=x>y?x:y;} const int N=81; const int M=81; lll qpow(lll a,lll b){ lll res=1; for(;b;b>>=1){ if(b&1)res*=a; a*=a; } return res; } void print(lll x){ if(!x)return; if(x)print(x/10); putchar(x%10+'0'); } int n,m; lll g[N][M],f[M][M][M],ans; int main(){ read(n);read(m);rep(i,1,n)rep(j,1,m)read(g[i][j]); rep(t,1,n){ lll tmp=0;memset(f,0,sizeof(f)); rep(i,1,m){ rep(j,0,i){ int k=i-j; if(j)cmax(f[i][j][k],f[i-1][j-1][k]+g[t][j]*qpow(2,i)); if(k)cmax(f[i][j][k],f[i-1][j][k-1]+g[t][m-k+1]*qpow(2,i)); if(i==m)cmax(tmp,f[i][j][k]); } } ans+=tmp; } if(!ans)printf("0"); print(ans); return 0; }