[P3625][APIO2009]采油区域 (前缀和)

这道题用二维前缀和可以做

难度还不算高,细节需要注意

调试了很久……

主要是细节太多了

#include<bits/stdc++.h>
using namespace std;
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define ll long long
#define N 1505
inline int read() {
    int f = 1, x = 0; char ch;
    do { ch = getchar(); if (ch == '-')f = -1; } while (ch<'0' || ch>'9');
    do { x = x * 10 + ch - '0'; ch = getchar(); } while (ch >= '0'&&ch <= '9');
    return f * x;
}
int m, n, k, ans;
int s[N][N],a[N][N],b[N][N],c[N][N],d[N][N];
int main()
{
    n = read(), m = read(), k = read();
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            int t = read();
            s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + t;
        }
    }
    for (int i = n; i >= k; i--)
        for (int j = m; j >= k; j--)
            s[i][j] -= s[i - k][j] + s[i][j - k] - s[i - k][j - k];
    for (int i = k; i <= n; i++)
        for (int j = k; j <= m; j++)
            a[i][j] = max(s[i][j], max(a[i - 1][j], a[i][j - 1]));
    for (int i = k; i <= n; i++)
        for (int j = m; j >= k; j--)
            b[i][j] = max(s[i][j], max(b[i][j + 1], b[i - 1][j]));
    for (int i = n; i >= k; i--)
        for (int j = k; j <= m; j++)
            c[i][j] = max(s[i][j], max(c[i][j - 1], c[i + 1][j]));
    for (int i = n; i >= k; i--)
        for (int j = m; j >= k; j--)
            d[i][j] = max(s[i][j], max(d[i][j + 1], d[i + 1][j]));

    for (int i = k; i <= n - k; i++)//1
        for (int j = k; j <= m - k; j++)
            ans = max(ans, a[i][j] + b[i][j + k] + c[i + k][m]);
    for (int i = k + k; i <= n; i++)//2
        for (int j = k; j <= m - k; j++)
            ans = max(ans, c[i][j] + d[i][j + k] + a[i - k][m]);
    for (int i = k + k; i <= n - k; i++)//6
        for (int j = k; j <= m; j++)
            ans = max(ans, s[i][j] + a[i - k][m] + c[i + k][m]);
    for (int i = k; i <= n - k; i++)//3
        for (int j = k; j <= m - k; j++)
            ans = max(ans, a[i][j] + c[i + k][j] + b[n][j + k]);
    for (int i = k; i <= n - k; i++)//4
        for (int j = k + k; j <= m; j++)
            ans = max(ans, a[n][j - k] + b[i][j] + d[i + k][j]);
    for (int i = k; i <= n - k; i++)//5
        for (int j = k + k; j <= m - k; j++)
            ans = max(ans, s[i][j] + a[n][j - k] + b[n][j + k]);
    cout << ans;
    return 0;
}

 

posted @ 2018-10-19 21:11  lincold  阅读(182)  评论(0编辑  收藏  举报