1. 程式人生 > >SenseTime Ace Coder Challenge 暨 商湯線上程式設計挑戰賽 A.雙人取數

SenseTime Ace Coder Challenge 暨 商湯線上程式設計挑戰賽 A.雙人取數

有一款雙人遊戲,遊戲的地圖是一張 n \times mn×m的平面,其中玩家 A 從地圖的左上角出發,通過向右和向下走的方式走到右下角,玩家 B 從右上角出發,通過向左和向下的方式走到左下角(每次只能走到上下左右相鄰的至多四個格子)。

每個格子有一個分數,玩家走到格子上就會獲得這個分數,當一個玩家得到這個分數後,格子的分數就會自動變為 00。遊戲最後的得分是兩個人獲得分數的總和。

即使兩個人同時進入一個格子,這個格子上的分數也只會被計入一次。

現在希望你幫忙計算出,這個遊戲能獲得的最高分是多少。

輸入格式

輸入第一行一個整數 TT。表示測試資料組數。

接下來輸入 TT 組資料。每組資料按照下面的規則輸入。

對於每組資料第一行輸入兩個整數 nn,mm,代表遊戲地圖的長和寬。

然後接下來的 nn 行每行輸入 mm 個整數,代表地圖上每個格子的分數。

1 \le T \le 151≤T≤15,3 \le n,m \le 10003≤n,m≤1000。

每個格子分數絕對值 \le 1000≤1000。

輸出格式

對於第i組資料,輸出格式形如"Case #i: x"(輸出不含引號),其中x表示該組資料對應的遊戲最高分。

題解:

重合的部分一定是連續的一行幾個,或連續的一列幾個。

字首和優化一下就行了。

#include <bits/stdc++.h>
#ifdef LOCAL
#define debug(x) cout<<#x<<" = "<<(x)<<endl;
#else
#define debug(x) 1;
#endif

#define chmax(x,y) x=max(x,y)
#define chmin(x,y) x=min(x,y)
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
#define lowbit(x) x&-x
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const int MOD = 1e9 + 7;
const double PI = acos (-1.);
const double eps = 1e-10;
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 5e5 + 5;

int a[1111][1111];
int d1[1111][1111][2]; // 0 上 1 左
int d2[1111][1111][2]; // 0 上 1 右
int d3[1111][1111][2]; // 0 下 1 右
int d4[1111][1111][2]; // 0 下 1 左


int pre1[1111][1111], pre2[1111][1111];
int maxn[1111];


int main() {
#ifdef LOCAL
    freopen ("input.txt", "r", stdin);
#endif
    int T, cas = 1;
    cin >> T;
    while (T--) {
        int n, m;
        scanf ("%d %d", &n, &m);
        for (int i = 0; i <= n + 1; i++)
            for (int j = 0; j <= m + 1; j++)
                for (int k = 0; k < 2; k++) {
                    d1[i][j][k] = d2[i][j][k] = d3[i][j][k] = d4[i][j][k] = -INF;
                }

        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++) scanf ("%d", &a[i][j]);
        d1[1][1][0] = d1[1][1][1] = a[1][1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                chmax (d1[i][j][0], max(d1[i - 1][j][0], d1[i - 1][j][1]) + a[i][j]);
                chmax (d1[i][j][1], max(d1[i][j - 1][0], d1[i][j - 1][1]) + a[i][j]);
            }
        }
        d2[1][m][0] = d2[1][m][1] = a[1][m];
        for (int i = 1; i <= n; i++) {
            for (int j = m; j >= 1; j--) {
                chmax (d2[i][j][0], max(d2[i - 1][j][0], d2[i - 1][j][1])+ a[i][j]);
                chmax (d2[i][j][1], max(d2[i][j + 1][0], d2[i][j + 1][1])+ a[i][j]);
            }
        }
        d3[n][m][0] = d3[n][m][1] = a[n][m];
        for (int i = n; i >= 1; i--) {
            for (int j = m; j >= 1; j--) {
                chmax (d3[i][j][0], max(d3[i + 1][j][0], d3[i + 1][j][1])+ a[i][j]);
                chmax (d3[i][j][1], max(d3[i][j + 1][0], d3[i][j + 1][1])+ a[i][j]);
            }
        }
        d4[n][1][0] = d4[n][1][1] = a[n][1];
        for (int i = n; i >= 1; i--) {
            for (int j = 1; j <= m; j++) {
                chmax (d4[i][j][0], max(d4[i + 1][j][0], d4[i + 1][j][1])+ a[i][j]);
                chmax (d4[i][j][1], max(d4[i][j - 1][0], d4[i][j - 1][1])+ a[i][j]);
            }
        }
     //   debug(d2[2][3][1])
        int ans = -INF;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++) pre1[i][j] = pre1[i][j - 1] + a[i][j];
        for (int j = 1; j <= m; j++)
            for (int i = 1; i <= n; i++) pre2[i][j] = pre2[i - 1][j] + a[i][j];
        for (int i = 1; i <= n; i++) {
            maxn[m + 1] = -INF;
            for (int j = m; j >= 1; j--) {
                maxn[j] = maxn[j + 1];
                for (int k = 0; k < 2; k++)
                    for (int l = 0; l < 2; l++)
                    if (k != 1 || l != 1)
                    chmax(ans, maxn[j] + d1[i][j][k] + d4[i][j][l] - a[i][j] * 2 - pre1[i][j - 1]);
                for (int k = 0; k < 2; k++)
                    for (int l = 0; l < 2; l++)
                    if (k != 1 || l != 1)
                    chmax (maxn[j], d2[i][j][k] + d3[i][j][l] - a[i][j] * 2  + pre1[i][j]);
                chmax (ans, d1[i][j][0] + d3[i][j][0] + d2[i][j][1] + d4[i][j][1] - a[i][j] * 3);
                chmax (ans, d1[i][j][1] + d3[i][j][1] + d2[i][j][0] + d4[i][j][0] - a[i][j] * 3);
               // debug(ans)
            }
        }
        for (int j = 1; j <= m; j++) {
            maxn[n + 1] = -INF;
            for (int i = n; i >= 1; i--) {
                maxn[i] = maxn[i + 1];
                for (int k = 0; k < 2; k++)
                    for (int l = 0; l < 2; l++)
                    if (k != 0 || l != 0)
                    chmax(ans, maxn[i] + d1[i][j][k] + d2[i][j][l] - a[i][j] * 2 - pre2[i - 1][j]);
                for (int k = 0; k < 2; k++)
                    for (int l = 0; l < 2; l++)
                    if (k != 0 || l != 0)
                    chmax (maxn[i], d4[i][j][k] + d3[i][j][l] - a[i][j] * 2  + pre2[i][j]);
            }
        }
        printf ("Case #%d: %d\n", cas++, ans);
    }
    return 0;
}