1. 程式人生 > >[HNOI2004]打鼴鼠

[HNOI2004]打鼴鼠

鼴鼠是一種很喜歡挖洞的動物,但每過一定的時間,它還是喜歡把頭探出到地面上來透透氣的。根據這個特點阿牛編寫了一個打鼴鼠的遊戲:在一個\(n*n\)的網格中,在某些時刻鼴鼠會在某一個網格探出頭來透透氣。你可以控制一個機器人來打鼴鼠,如果i時刻鼴鼠在某個網格中出現,而機器人也處於同一網格的話,那麼這個鼴鼠就會被機器人打死。而機器人每一時刻只能夠移動一格或停留在原地不動。機器人的移動是指從當前所處的網格移向相鄰的網格,即從座標為(i,j)的網格移向(i-1, j),(i+1, j),(i,j-1),(i,j+1)四個網格,機器人不能走出整個\(n*n\)的網格。遊戲開始時,你可以自由選定機器人的初始位置。

現在知道在一段時間內,鼴鼠出現的時間和地點,請編寫一個程式使機器人在這一段時間內打死儘可能多的鼴鼠。

輸入輸出格式

輸入格式

從檔案input.txt中讀入資料,檔案第一行為n(n<=1000), m(m<=10000),其中m表示在這一段時間內出現的鼴鼠的個數,接下來的m行中每行有三個資料time,x,y表示有一隻鼴鼠在遊戲開始後time個時刻,在第x行第y個網格里出現了一隻鼴鼠。Time按遞增的順序給出。注意同一時刻可能出現多隻鼴鼠,但同一時刻同一地點只可能出現一隻鼴鼠。

輸出格式

輸出檔案output.txt中僅包含一個正整數,表示被打死鼴鼠的最大數目。

樣例輸入

2 2
1 1 1
2 2 2

樣例輸出

2

題解

類似LIS問題,因為所有點按照時間遞增給出,所以可以將所有點按讀入順序排列,當兩點之間的時間差大於它們的距離差時,我們就說這兩個點可以互相到達。因此,只需要從前往後依次尋找到達每個點前最多可以到達的點的數量即可。

#include<bits/stdc++.h>
using namespace std;
int dp[10050],n,m;
struct edge{
    int t,x,y;
}E[10005];
int LIS_nn(){
    int now_times=0;
    int ans=0;
    for(int i=1;i<=m;i++){
        dp[i]=1;
        for(int j=1;j<i;j++){
            if(abs(E[i].t-E[j].t) >= abs(E[i].x-E[j].x) + abs(E[i].y-E[j].y)){
                dp[i]=max(dp[i],dp[j]+1);
            }
        }
        ans=max(ans,dp[i]);
    }
    return ans;
}
int t,x,y;
int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++)cin>>E[i].t>>E[i].x>>E[i].y;
    cout<<LIS_nn();
    return 0;
}