原题链接
https://ac.nowcoder.com/acm/problem/16645
思路
考虑后发现每一行独立,可以每一行单独算最大值,最后加起来即可,f[l][r]表示考虑第i行的l到r这个区间,能取到的最大值,这里可以记忆化搜索。转移方程为:f[l][r] = max(f[l + 1][r] + a[l] * x, f[l][r - 1] + a[r] * x),其中x是2^i。注意要用int128
int128读写模板
INT read()
{
INT x = 0, f = 1;
char c = getchar();
while (c < ‘0‘ || c > ‘9‘) {
if (c == ‘-‘) f = -1;
c = getchar();
}
while (c >= ‘0‘ && c <= ‘9‘) {
x = (x << 1) + (x << 3) + c - ‘0‘;
c = getchar();
}
return f * x;
}
void print(INT x)
{
if (x < 0) {
putchar(‘-‘);
x = -x;
}
if (x / 10) print(x / 10);
putchar(x % 10 + ‘0‘);
}
题目代码
#include <bits/stdc++.h>
using namespace std;
#define INT __int128
const int N = 100;
INT a[N];
INT f[N][N];
INT n, m;
INT read()
{
INT x = 0, f = 1;
char c = getchar();
while (c < ‘0‘ || c > ‘9‘) {
if (c == ‘-‘) f = -1;
c = getchar();
}
while (c >= ‘0‘ && c <= ‘9‘) {
x = (x << 1) + (x << 3) + c - ‘0‘;
c = getchar();
}
return f * x;
}
void print(INT x)
{
if (x < 0) {
putchar(‘-‘);
x = -x;
}
if (x / 10) print(x / 10);
putchar(x % 10 + ‘0‘);
}
INT dfs(int l, int r) {
if (f[l][r]) return f[l][r];
INT x = (INT)1 << (m - r + l);
if (l == r) return a[l] * x;
f[l][r] = max(dfs(l + 1, r) + a[l] * x, dfs(l, r - 1) + a[r] * x);
return f[l][r];
}
int main() {
INT ans = 0;
n = read(), m = read();
for (int i = 1; i <= n; i ++ ) {
memset(f, 0, sizeof f);
for (int j = 1; j <= m; j ++ ) a[j] = read();
ans += dfs(1, m);
}
print(ans);
puts("");
return 0;
}
原文:https://www.cnblogs.com/lautoh/p/14782797.html