原题链接:https://www.luogu.org/problemnew/show/P1005
我的思路
首先看小数据,基本可以猜测是要用大数了,其次看一下大的数据,那就确定是要用大数了。
然后有点显然的是,每一行之间是互不干涉的,因此可以把每一行单独来处理,实际上每一行的处理方法应该是一致的。
对于每一行的处理,我们可以看出,对于每次取数,要么是取行首,要么是取行尾。那么 dp[l][r]=max(dp[l+1][r]+a[l],dp[l][r−1]+a[r]) d p [ l ] [ r ] = m a x ( d p [ l + 1 ] [ r ] + a [ l ] , d p [ l ] [ r − 1 ] + a [ r ] ) ,其中 dp[l][r] d p [ l ] [ r ] 表示 [l,r] [ l , r ] 能取到的最大值, a[i] a [ i ] 表示已经乘方基础上的值。这个转移方程就是说,一个区间的最大值,是由最后一个取最左加上去掉最左的最大值,与最后一个取最右加上去掉最右的最大值,其中的较大一个来表示。当然这个方程可以有多种写法。
代码
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.StringTokenizer;
public class Main {
static final int maxn = 100;
static int n, m;
static int[] a = new int[maxn];
static BigInteger[][] dp = new BigInteger[maxn][maxn];
static final BigInteger TWO = BigInteger.valueOf(2);
public static void main(String[] args) {
BigInteger result = BigInteger.ZERO;
FastScanner fs = new FastScanner();
n = fs.nextInt();
m = fs.nextInt();
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
a[j] = fs.nextInt();
}
for (int j = 0; j < m; j++) {
dp[j][j] = BigInteger.valueOf(a[j]);
}
for (int j = 1; j <= m; j++) { // 区间长度
for (int k = 0; k < m - j; k++) { // 起点
int e = j + k;
BigInteger t1 = BigInteger.valueOf(a[k]).add(dp[k + 1][e].multiply(TWO));
BigInteger t2 = BigInteger.valueOf(a[e]).add(dp[k][e - 1].multiply(TWO));
if (t1.compareTo(t2) > 0) {
dp[k][e] = t1;
} else {
dp[k][e] = t2;
}
}
}
result = result.add(dp[0][m - 1].multiply(TWO));
}
System.out.println(result);
}
public static class FastScanner {
private StringTokenizer st;
private BufferedReader br;
void eat(String s) {
st = new StringTokenizer(s);
}
public FastScanner() {
br = new BufferedReader(new InputStreamReader(System.in));
eat("");
}
public FastScanner(String s) {
try {
br = new BufferedReader(new FileReader(new File(s)));
eat("");
} catch (Exception e) {
// TODO: handle exception
}
}
public String nextLine() {
try {
return br.readLine();
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
public boolean hasNext() {
while (!st.hasMoreTokens()) {
String s = nextLine();
if (s == null) {
return false;
}
eat(s);
}
return true;
}
public String nextToken() {
hasNext();
return st.nextToken();
}
public int nextInt() {
return Integer.valueOf(nextToken());
}
}
}