链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
思路:
直接枚举这个图中的拐点
这个拐点是经过左右平移到上下平移或者上下平移到左右平移
假设这个点事左到右后然后再从下到上
左到右就相当于走了个最长上升子序列,然后再从下到上
从下到上的过程你可以反过来看,就是从上走到下,就相当从上到下走了个最长下降子序列
然后最长上升/下降子序列可以用dp+二分来求
按题解的话来说就是
预处理出对于每个单元格四个方向上最多跳多少个单元格可以跳到当前单元格(最长上升子序列),以及从当前单元格跳出最多能跳多少个单元格(最长下降子序列)
-----------------------------------
下面是最长上升子序列的代码
memset(q,0x3f,sizeof q);
q[0]=-inf;
int maxx=0;
for(int i=0;i
最长下降子序列代码
for (int i = 0; i < n; i++) {
cin >> v[i];
}
dp.push_back(v[0]);
for (int i = 1; i < n; i++) {
if (v[i] < dp.back()) dp.push_back(v[i]);
else {
int l = 0, r = dp.size()-1;
while (l < r) {
int m = l + (r - l) / 2;
if (v[i] < dp[m])l = m + 1;
else r = m;
}
dp[l] = v[i];
}
-------------------
经过每个点4个方向的预处理
#include
#include
#include//accumulate(be,en,0)
#include//rfind("string"),s.find(string,begin)!=s.npos,find_first _of(),find_last_of()
#include//to_string(value),s.substr(int begin, int length);
#include
#include
#include//res.erase(unique(res.begin(), res.end()), res.end()),reverse(q.begin(),q.end()),vector().swap(at[mx])
#include//priority_queue(big) /priority_queue, greater> q(small)
#include
//#include