https://neooj.com/oldoj/problem.php?id=1532
最优路径为4-> 3-> 2-> 1,得分为4+1+4=9。
这道题比线性动归稍微难了一点点。
难点在数据结构上。
可以开结构体,也可以二维数组,由于结构体码长比较恶心,所以我用的二维数组。
为什么呢?
因为算花费(华丽度)的时候要用到坐标,所以要把坐标和高度同时存进去。
一定要多开至少1位!别心疼那点空间,我就因为这个没A。
我们把状态设置成dp[i]表示从山脚跳到高度为i的点的华丽度的最大值。
然后还会有初始化的一个难点。
我们把初值设定为直接从i点跳到山脚的华丽度。
为什么呢?
因为我们状态的设定是反着来的。(从山脚往山顶蹦)
然后我们在动归松弛的时候就会发现,这其实和floyd的实现原理很像。
就是中间找断点看看能否松弛。
这也是一个很重要的思想
希望大家慢慢掌握
上代码:
#include<cstdio> #include<algorithm> #include<cmath> using namespace std; int m[2600][3]; int n; int calc(int x,int y) { return (abs(m[x][1]-m[y][1])+abs(m[x][2]-m[y][2]))*(abs(m[x][1]-m[y][1])+abs(m[x][2]-m[y][2])); } int dp[2600]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { int a; scanf("%d",&a); m[a][0]=a; m[a][1]=i; m[a][2]=j; } for(int i=1;i<=n*n;i++) dp[i]=calc(i,1); for(int i=2;i<=n*n;i++) for(int j=1;j<i;j++) dp[i]=max(dp[i],dp[j]+calc(i,j)); printf("%d",dp[n*n]); return 0; }
原文:https://www.cnblogs.com/fusiwei/p/11237312.html