Codevs 1256 打鼹鼠
从坐标为(i,j)的网格移向(i-1, j),(i+1, j),(i,j-1),(i,j+1)四个网格
很容易想到 f[i][x][y] = max{f[i-1][x+xx[i]][y+yy[i]]+1} 但是空间显然不允许。。。
你可以自由选定机器人的初始位置。
这句话也比较让人头疼
但是,t时刻出现的地鼠,能不能打,只和他的位置与前面时刻出现地鼠的位置有关,(相对位置,所以说不用管现在到底在哪个格子)就是说,如果dist(i,j)<=a[i].t-a[j].t,那这个地鼠就可以打到,
f[i] = max(f[i],f[j]+1); 其中j<i 且 dist(i,j)<=a[i].t-a[j].t
于是这就变成了最长上升子序列的模型。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cmath> #define M 10010 using namespace std; struct node { int t,x,y; }a[M]; int f[M]; //f[i]表示前i个地鼠能获得的最大价值 int n,m,ans; inline int abs(int a){ if (a>0) return a;else return -a;} inline int dis(int i,int j){ return abs(a[i].x-a[j].x) + abs(a[i].y - a[j].y);} int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) { f[i] = 1; //注意初值,f[i]至少是1 scanf("%d%d%d",&a[i].t,&a[i].x,&a[i].y); for (int j=i-1;j>=1;j--) if (dis(i,j)<=a[i].t-a[j].t) { f[i] = max(f[i],f[j]+1); } ans = max(ans,f[i]); } printf("%d",ans); }