【P1005 [NOIP2007 提高组] 矩阵取数游戏】
思路:
用dp[i][j]代表区间变为【i,j】时,获得的最大分数当区间变为[i][j]时,一定是由【i-1,j】或者是[i,j-1]这两个符合条件的方程式中转移过来的,在第m-(j-i)-1次i取走了当前值。
因此状态转移方程就是 dp[i][j]=max(dp[i-1][j]+a[t][i-1]mypow(len),dp[i][j+1]+a[t][j+1]mypow(len));
当区间长度为1时,它是没有办法把最后一个数字取出来的。因此在这里要在重新加上
#include <cstdio>
#include <iostream>
#include <cstring>
#define int __int128
using namespace std;
int n,m,jv[85][85],ans;
int f[85][85];
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){ch=getchar();if(ch=='-')f=-1;}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline int solve(int hang){
memset(f,0,sizeof(f));
for(int les=0;les<=m;les++){[
for(int rar=1;les+rar<=m;rar++){
f[rar][rar+les]=max(2*f[rar+1][rar+les]+2*jv[hang][rar],2*f[rar][rar+les-1]+2*jv[hang][rar+les]);
}
}
return f[1][m];
}
inline void output(__int128 x){
if(x>9)
output(x/10);
putchar(x%10+'0');
}
main(){
n=read();m=read();
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
jv[i][j]=read();
}
}
for(int i=1;i<=n;i++) ans+=solve(i);
output(ans);
return 0;
}