UVA

来源:互联网 发布:淘宝首页热点 编辑:程序博客网 时间:2024/06/16 12:32

比较经典的路子了:
用 sum [ k ] [ i ] [ j ] 表示 第k层中 前 i 行 且 前 j 列 的所有数组和
这样类似数组前缀和,可以 在 O(1)的时间内求出 第 i 行 第 j 列 到 第 x 行 第 y 列的 中间部分的数组和,
然后 再用一维的 数组 g[ ] 存 每一层 当前选定部分的 和,就相当于求最大子数组和,
可以枚举每一层的选定部分

ps:
注意输入的 题中所说的 A B C,A 相当于高度,B C 相当于每一层的长和宽
还有 INF 定义的时候要注意是 long long 范围中很大的一个值

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <set>#include <map>#include <stack>#include <queue>#include <ctype.h>#include <vector>#include <algorithm>#define in freopen("in.txt", "r", stdin)#define out freopen("out.txt", "w", stdout)// cout << "  ===  " << endl;using namespace std;typedef long long ll;const int maxn = 20 + 7, mod = 1e9+7;int T, L, R, H;ll mp[maxn][maxn][maxn], sum[maxn][maxn][maxn], g[maxn];const ll INF = 0x3f3f3f3f3f3f3f3f;void init() {    memset(sum, (ll)0, sizeof sum);    for(int k = 1; k <= H; ++k) {        for(int i = 1; i <= L; ++i) {            for(int j = 1; j <= R; ++j) {                scanf("%lld", &mp[k][i][j]);                sum[k][i][j] = mp[k][i][j] + (sum[k][i][j-1] + sum[k][i-1][j] - sum[k][i-1][j-1]);                //cout << sum[k][i][j] << " ";            }            //cout << endl;        }        //cout << endl;    }}ll get_max() {    ll sum = 0, max_ = -INF;    for(int i = 1; i <= H; ++i) {        sum += g[i];        if(sum > max_) max_ = sum;        if(sum < 0) sum = 0;    }//cout << "  ===  " << max_ << endl;    return max_;}ll solve() {    ll ans = -INF;    for(int i = 1; i <= L; ++i) {        for(int j = 1; j <= R; ++j) {            for(int x = i; x <= L; ++x) {                for(int y = j; y <= R; ++y) {                    memset(g, (ll)0, sizeof g);                    for(int k = 1; k <= H; ++k) {                        g[k] = sum[k][x][y] - sum[k][x][j-1] - sum[k][i-1][y]  + sum[k][i-1][j-1];                        //cout << g[k] << "  ";                    }                    //cout << endl;                    ans = max(ans, get_max() );                }            }        }    }    return ans;}int main() {    //in;    //out;    scanf("%d", &T);    getchar();    while(T--) {        scanf("%d %d %d", &H, &L, &R);        init();        printf("%lld\n", solve() );        if(T) puts("");        getchar();    }    return 0;}
原创粉丝点击