【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;
}