Vijos P1441 打鼹鼠

Vijos P1441 打鼹鼠


题目

背景

鼹鼠是一种很喜欢挖洞的动物,但每过一定的时间,它还是喜欢把头探出到地面上来透透气的。
描述

根据这个特点阿Q编写了一个打鼹鼠的游戏:在一个n*n的网格中,在某些时刻鼹鼠会在某一个网格探出头来透透气。你可以控制一个机器人来打鼹鼠,如果i时刻鼹鼠在某个网格中出现,而机器人也处于同一网格的话,那么这个鼹鼠就会被机器人打死。而机器人每一时刻只能够移动一格或停留在原地不动。机器人的移动是指从当前所处的网格移向相邻的网格,即从坐标为(i,j)的网格移向(i-1, j),(i+1, j),(i,j-1),(i,j+1)四个网格,机器人不能走出整个n*n的网格。游戏开始时,你可以自由选定机器人的初始位置。
现在你知道在一段时间内,鼹鼠出现的时间和地点,希望你编写一个程序使机器人在这一段时间内打死尽可能多的鼹鼠。
格式

输入格式

文件第一行为n(n<=1000), m(m<=10000),其中m表示在这一段时间内出现的鼹鼠的个数,接下来的m行每行有三个数据time,x,y表示有一只鼹鼠在游戏开始后time个时刻,在第x行第y个网格里出现了一只鼹鼠。Time按递增的顺序给出。注意同一时刻可能出现多只鼹鼠,但同一时刻同一地点只可能出现多只鼹鼠。
输出格式

输出文件中仅包含一个正整数,表示被打死鼹鼠的最大数目。
样例1

样例输入1

2 2
1 1 1
2 2 2

样例输出1

1

限制

各个测试点1s


题解

DP

首先,如果要打某个时间 i i 时的某个鼹鼠的位置 (x1,y1) ( x 1 , y 1 ) 一定是从前面某个时间 j j 时的某个鼹鼠的位置 (x2,y2) ( x 2 , y 2 ) 走过来的或者是作为起始点

所以状态转移的时候只要判断 i i - j j 是否大于 abs a b s ( x1 x 1 - x2 x 2 )+ abs a b s ( y1 y 1 - y2 y 2 ) 即可

然后我们还可以优化一下

如果状态转移相差的时间超过改点到四个角的最大值,那么就不用继续做这个点了,因为,这前面的点一定会转移到已经判断并转移过的点里。


代码

#include
using namespace std;

int n,m,ans;
int x[10005],y[10005],f[10005],t[10005];

int readln()
{
    int x=0;
    char ch=getchar();
    while (ch<'0'||ch>'9') ch=getchar();
    while ('0'<=ch&&ch<='9') x=x*10+ch-48,ch=getchar();
    return x;
}

int abs(int x){return x<0?-x:x;}

int dist(int a,int b){return abs(x[a]-x[b])+abs(y[a]-y[b]);}

int max(int x,int y){return x>y?x:y;}

int main()
{
    n=readln();m=readln();
    for (int i=1;i<=m;i++)
    {
        f[i]=1;
        t[i]=readln();x[i]=readln();y[i]=readln();
        for (int j=i-1;j>0;j--)
        {
            if (dist(i,j)<=t[i]-t[j]) f[i]=max(f[i],f[j]+1);
            if (t[i]-t[j]>=2*n-2) break;
        }
    }
    for (int i=1;i<=m;i++) ans=max(ans,f[i]);
    printf("%d",ans);
    return 0;
}

你可能感兴趣的:(DP,vijos)