領土劃分

領土劃分


問題描述

著名的女王,陽姐•查蘭•伊麗莎白一世有兩個寵物,一個叫大黃,一個叫小昊。
女王賜予了這兩個寵物一份 NM 的土地。
這片土地由 NM 個長度爲一單位的小正方形構成,每一個小正方形種植水稻或者小麥,但種植的量可能不同。
大黃喜歡吃飯,也就是說,他希望他的領地裏的水稻種植量多,類似的,小昊喜歡吃麪,所以他希望他的領地裏的小麥種植量多。
爲了這片土地的劃分,大黃與小昊經常發生狗咬狗、相煎何太急的慘劇。
現在女王決定,派出一輛推土機,這輛推土機從左上角開始,每次向右向下或者向右下移動一個格子,直到走到土地的右下角爲止,推土機經過的格子將變爲廢墟。
這樣就會將土地分成上下兩塊,其中右上的那一塊歸小昊,左下的那一塊歸大黃。
現在女王想知道,這輛推土機如何移動,能夠使得大黃領地中水稻種植總量和小昊領地中小麥種植總量之和最大?


輸入

輸入文件名爲Divide.in。
輸入第一行包含兩個正整數 NM ,表示土地的行數與列數。
下接一個 NM 的矩陣描述這塊土地的信息,其中,每個格子的信息按照如下方式表示:若該格子種的是水稻,則形式爲“JX”,其中 X 爲該格子中水稻的種植量;若該格子種的是小麥,則形式爲“KX”,其中 X 爲該格子中小麥的種植量。
保證種植量均爲小於等於 99 的非負整數,且每一行中相鄰兩個格子之間有逗號隔開。


輸出

輸出文件名爲Divide.out。
輸出第一行包含一個正整數,爲可能的最大的兩種作物種植量總和。


輸入樣例

4 3
K2 K3 K5
J3 K1 J1
J2 J4 K1
K1 K3 J3


輸出樣例

17


樣例解釋

移動方法爲向右下,向右下,向下。總和爲 (3+2+4)+(3+5)=17


數據範圍

40% 的數據保證 1<=N,M<=100
100% 的數據保證 1<=N,M<=1500 。數據保證有梯度。


Solution

fi,j 表示當前在 (i,j) ,而接下來的路線是一直向右,到達邊界後一直向下的最大值(奇葩的狀態表示,就我想的出來)。
首先,當前位置可以是從左邊走過來的。若是從左邊走過來的,則 fi,j=fi,j1
其次,當前位置也可以是從上邊走過來的。若是從上邊走過來的,則
fi,j=fi1,j+(i1,j+1)(i1,m) 一段小麥的和(i,j)(i,m1) 一段水稻的和。
從左上走過來的同理。


Code

#include <iostream>
#include <cstdio>
#include <cstring>

#define Max(x,y) ((x)>(y)?(x):(y))

using namespace std;

int n,m;

int MI[1510][1510],DA[1510][1510];
int f[1510][1510];

char str[100000];

int main(){

    freopen("divide.in","r",stdin);
    freopen("divide.out","w",stdout);

    memset(f,-1,sizeof f);

    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            char ch;int num=0,q=1;
            scanf("%s",str);
            ch=str[0];
            while(str[q]<'0'||str[q]>'9')q++;
            while(str[q]>='0'&&str[q]<='9'){num=num*10+str[q]-'0';q++;}
            if(ch=='K'){
                MI[i][j]=MI[i-1][j]+MI[i][j-1]-MI[i-1][j-1]+num;
                DA[i][j]=DA[i-1][j]+DA[i][j-1]-DA[i-1][j-1];
            }
            else{
                MI[i][j]=MI[i-1][j]+MI[i][j-1]-MI[i-1][j-1];
                DA[i][j]=DA[i-1][j]+DA[i][j-1]-DA[i-1][j-1]+num;
            }
        }
    if(n==1||m==1){
        printf("0\n");
        return 0;       
    }
    for(int i=1;i<=m;i++){
        f[1][i]=DA[n][m-1]-DA[1][m-1];
    }
    for(int i=2;i<=n;i++){
        for(int j=1;j<=m;j++){
            f[i][j]=f[i][j-1];
            f[i][j]=Max(f[i][j],f[i-1][j]+MI[i-1][m]-MI[i-1][j]-MI[i-2][m]+MI[i-2][j]-(DA[i][m-1]-DA[i][j-1]-DA[i-1][m-1]+DA[i-1][j-1]));
            if(j-1!=0){
                f[i][j]=Max(f[i][j],f[i-1][j-1]+MI[i-1][m]-MI[i-1][j-1]-MI[i-2][m]+MI[i-2][j-1]-(DA[i][m-1]-DA[i][j-1]-DA[i-1][m-1]+DA[i-1][j-1]));
            }
        }
    }
    printf("%d\n",f[n][m]);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章