VJ 1474 雷曼兔
描述
这次,OI山成为了雷曼兔那无尽的冒险传说的新舞台!传说OI山中埋藏着巨大的宝藏,伴随着这个传说的是一个迷题:最瑰丽的舞者将达至精灵世界的彼岸……
经过仔细推敲,雷曼兔发现这是一个提示宝藏埋藏位置的谜语,在该谜语中指出了一个特定的路径,只有经过了该路径宝藏才会出现,具体情况如下:
OI山的地势图可以看作一个N*N的数字矩阵,由1-N^2的数字组成(每个数字出现且仅出现一次),这些数字表示每个地点的地势高低。雷曼兔的出发点在
最高的山顶处,并且每次雷曼兔可以从其当前所在的位置跳跃到任何一个比当前地点高度低的位置,假设雷曼兔该次跳跃从坐标(x1,y1)跳到了坐标
(x2,y2),则这次跳跃的华丽度定义为v=(|x1-x2|+|y1-y2|)^2。而开启宝藏秘密的路径就是从山顶不断跳跃直到山底(高度最低点)
的华丽度总和最高的路径,而现在我们想要知道的是这个最高的华丽度总和是多少
格式
输入格式
第一行包括一个整数n(n<=50)表示地图的长宽。
接下来n行每行包括n个数表示每个地点的高度。
输出格式
输出包括一个整数ans,表示从山顶到山底最高华丽度总和
提示
最优路径为4->3->2->1,得分为4+1+4=9。
DP.但是有个疑问就是n<50, 但是数组开(50 + 10)^2会RE,但是开到3000就不会。。什么情况
CODE:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #define REP(i, s, n) for(int i = s; i <= n; i ++) #define REP_(i, s, n) for(int i = n; i >= s; i --) #define MAX_N 50 + 10 using namespace std; int n, map[3000][2]; int F[3000]; int main(){ int tmp = 0; scanf("%d", &n); REP(i, 1, n) REP(j, 1, n){ scanf("%d", &tmp); map[tmp][1] = i; map[tmp][2] = j; } memset(F, 0, sizeof(F)); REP_(i, 2, n * n) REP_(j, 1, i - 1){ int ans = abs(map[i][1] - map[j][1]) + abs(map[i][2] - map[j][2]); ans *= ans; if(F[i] + ans > F[j]) F[j] = F[i] + ans; } int ans = 0; REP(i, 1, n) if(F[i] > ans) ans = F[i]; printf("%d\n", ans); return 0; }