bzoj3208 花神的秒題計劃Ⅰ 【記憶化】

Description

背景【backboard】:
 Memphis等一羣蒟蒻出題中,花神湊過來秒題……
描述【discribe】:
 花花山峯巒起伏,峯頂常年被雪,Memphis打算幫花花山風景區的人員開發一個滑雪項目。
 我們可以把風景區看作一個n*n的地圖,每個點有它的初始高度,滑雪只能從高處往低處滑【嚴格大於】。但是由於地勢經常變動【比如雪崩、滑坡】,高度經常變化;同時,政府政策規定對於每個區域都要間歇地進行保護,防止環境破壞。現在,滑雪項目的要求是給出每個n*n個點的初始高度,並給出m個命令,C a b c表示座標爲a,b的點的高度改爲c;S a b c d表示左上角爲a,b右下角爲c,d的矩形地區開始進行保護,即不能繼續滑雪;B a b c d表示左上角爲a b,右下角爲c d的矩形地區取消保護,即可以開始滑雪;Q表示詢問現在該風景區可以滑雪的最長路徑爲多少。對於每個Q要作一次回答。
 花神一看,這不是超簡單!立刻秒出了標算~

Input

第一行n,第二行開始n*n的地圖,意義如上;接下來一個m,然後是m個命令,如上

Output

對於每一個Q輸出單獨一行的回答

Sample Input

5
1 2 3 4 5
10 9 8 7 6
11 12 13 14 15
20 19 18 17 16
21 22 23 24 25
5
C 1 1 3
Q
S 1 3 5 5
S 3 1 5 5
Q

Sample Output

24
3

樣例解釋:
第一個Q路線爲:25->24->23->22….->3->2
第二個Q的路線爲:10->9->2

HINT

100%的數據:1<=n<=700;1<=m<=1000000;其中Q、S、B操作總和<=100;

題中所有數據不超過2*10^9


Analyse

記憶化搜索,就夠了。很暴力。

CODE:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#define INF 0x7fffffff
#define SUP 0x80000000
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;

typedef long long LL;
const int N=1007;

int gra[N][N],dp[N][N],go[][2]={{-1,0},{1,0},{0,1},{0,-1}};
bool vis[N][N];
int maxx,n,m;

void S_B(int a,int b,int c,int d,int v)
{
    for(int i=a;i<=c;i++)
    {
        for(int j=b;j<=d;j++)
        {
            vis[i][j]=v;
        }
    }
}

void dfs(int x,int y)
{
    if(vis[x][y]) return;
    if(dp[x][y]!=-1) return;
    dp[x][y]=1;
    int xx,yy;
    for(int i=0;i<4;i++)
    {
        xx=x+go[i][0];
        yy=y+go[i][1];
        if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&gra[xx][yy]>gra[x][y])
        {
            dfs(xx,yy);
            dp[x][y]=max(dp[x][y],dp[xx][yy]+1);
        }
    }
    maxx=max(dp[x][y],maxx);
}

int main()
{
    while(scanf("%d",&n)==1)
    {
        mem(vis,0);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&gra[i][j]);
            }
        }
        scanf("%d",&m);
        char op[10];
        int a,b,c,d;
        for(int i=0;i<m;i++)
        {
            scanf("%s",op);
            if(op[0]=='C')
            {
                scanf("%d%d%d",&a,&b,&c);
                gra[a][b]=c;
            }
            else if(op[0]=='S')
            {
                scanf("%d%d%d%d",&a,&b,&c,&d);
                S_B(a,b,c,d,1);
            }
            else if(op[0]=='B')
            {
                scanf("%d%d%d%d",&a,&b,&c,&d);
                S_B(a,b,c,d,0);
            }
            else
            {
                mem(dp,-1);
                maxx=0;
                for(int j=1;j<=n;j++)
                {
                    for(int k=1;k<=n;k++)
                        dfs(j,k);
                }
                printf("%d\n",maxx);
            }
        }

    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章