【JZOJ 5838】【廣州市選2011一試】旅遊路線 (前綴和)

問題描述
GZOI隊員們到X鎮遊玩。X鎮是一個很特別的城鎮,它有m+1條東西方向和n+1條南北方向的道路,劃分成m*n個區域,這些區域標從北到南、從西到東的座標標識爲從座標 (1,1) 到座標(m,n)。 GZOI隊員們預先對這m*n個區域打分V(i,j)(分數可正可負)。分數越高表示他們越想到那個地方,越低表示他們越不想去。爲了方便遊玩,隊員們需要選定一個連續的區域集合作爲活動範圍。例如,如果他們選擇了最西北的區域(m1,nl)和最東南(m2,n2)區域(m1<=m2,n1<=n2),那他們的活動範圍是 {D(i,j)|m1<=i<=m2,n1<=j<=n2},其遊覽總分則爲這些活動範圍的區域總分。 GZOI隊員們希望他們活動範圍內的區域的分值總和最大。你的任務是編寫一個程序,求出他們的活動範圍(m1,nl),(m2,n2〉。
輸入
輸入第一行爲整數m(1<=m<=200),n(1<=n<=200),用空格隔開 下面爲m行,每行有n列整數,其中第i行第j列的整數,代表V(i,j),每個整數之間用空格隔開,每個整數的範圍是 [-200000,200000],輸入數據保證這些整數中,至少存在一個正整數。
輸出
輸出只有一行,爲最高的分值。
樣例輸入
4 5
1 -2 3 -4 5
6 7 8 9 10
-11 12 13 14 -15
16 17 18 19 20
樣例輸出
146
算法討論
預處理每行的前綴和,枚舉從哪一列開始,行數從1到n的矩形,若分值小於零,就把ans清零接着做。

#include <cstdio>
#define MAX_N 206
#define LL long long
using namespace std;
int a[MAX_N][MAX_N],f[MAX_N][MAX_N],n,m;
LL s,Max;

int max(int a,int b)
{
    return a>b?a:b;
}

int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
        {
            scanf("%d",&a[i][j]);
            f[i][j]=f[i][j-1]+a[i][j];
        }
    for (int k=1;k<=m;k++)
        for (int j=k;j<=m;j++)
        {
            s=0;
            for (int i=1;i<=n;i++)
            {
                s+=(f[i][j]-f[i][k-1]);
                Max=max(s,Max);
                if (s<0)
                    s=0;
            }
        }
    printf("%lld",Max);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章