以中间某点为峰值的双向上升子序列
字数
1420 字
阅读时间
6 分钟
- 原题:Acwing 1014
登山
题目描述
五一到了,ACM队组织大家去登山观光,队员们发现山上一共有
同时队员们还有另一个登山习惯,就是不连续浏览海拔相同的两个景点,并且一旦开始下山,就不再向上走了
队员们希望在满足上面条件的同时,尽可能多的浏览景点,你能帮他们找出最多可能浏览的景点数么?
输入格式
第一行包含整数
第二行包含
输出格式
输出一个整数,表示最多能浏览的景点数。
数据范围
输入样例
8
186 186 150 200 160 130 197 220
输出样例
4
题解
思路:
根据题意:需要满足以下几个条件:
- 按照编号递增的顺序来浏览
必须是子序列 - 连续浏览的相邻两个景点的高度不能相同
- 一旦开始下山,就不再往上走了
走过的路线一定是先上升再下降 路线形如: 目标:要求求出最多能浏览多少个景点?
分析:闫氏DP分析法
具体思路:从a[1]开始一直到a[n],将所有满足该路线形状的子序列共分为
代码:
c++
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
int n;
int f[N], g[N];
int a[N];
int main()
{
cin >> n;
for (int i = 1; i <= n; i ++)
cin >> a[i];
// 从前往后求解最长上升子序列问题 ------ 正向LIS
for (int i = 1; i <= n; i ++)
{
f[i] = 1;
for (int j = 1; j < i; j ++)
if (a[i] > a[j])
f[i] = max(f[i], f[j] + 1);
}
// 从后往前求解最长上升子序列 ------ 反向LIS
for (int i = n; i; i --)
{
g[i] = 1;
for (int j = n; j > i; j --)
if (a[i] > a[j])
g[i] = max(g[i], g[j] + 1);
}
// 求解最大值
int res = 0;
for (int i = 1; i <= n; i ++)
res = max(res, f[i] + g[i] - 1); // 因为以 a[i] 为峰值,且正向LIS和反向LIS的求解过程中均包含了a[i]这个景点,重复了,所以要减 1
cout << res;
return 0;
}
原题:ACwing 482
变形题:合唱队形
题目描述
合唱队形是指这样的一种队形:设
你的任务是,已知所有
输入格式
输入的第一行是一个整数
第二行有
输出格式
输出包括一行,这一行只包含一个整数,就是最少需要几位同学出列。
数据范围
输入样例:
8
186 186 150 200 160 130 197 220
输出样例:
4
解析:
本题思路与登山一致,登山求的是从左到右过程中,以某一个景点为最高的峰值时,能经过的最多的景点的数量。 而本题则是在此基础上的一点更改,换成登山的理解就是:找到符合要求的能经过的最多的景点数以后,再求出没去的景点数并输出
代码:
c++
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
int n;
int f[N], g[N];
int a[N];
int main()
{
cin >> n;
for (int i = 1; i <= n; i ++)
cin >> a[i];
// 从前往后求解最长上升子序列问题 ------ 正向LIS
for (int i = 1; i <= n; i ++)
{
f[i] = 1;
for (int j = 1; j < i; j ++)
if (a[i] > a[j])
f[i] = max(f[i], f[j] + 1);
}
// 从后往前求解最长上升子序列 ------ 反向LIS
for (int i = n; i; i --)
{
g[i] = 1;
for (int j = n; j > i; j --)
if (a[i] > a[j])
g[i] = max(g[i], g[j] + 1);
}
// 求解最大值
int res = 0;
for (int i = 1; i <= n; i ++)
res = max(res, f[i] + g[i] - 1); // 因为以 a[i] 为峰值,且正向LIS和反向LIS的求解过程中均包含了a[i]这个景点,重复了,所以要减 1
cout << n - res;
return 0;
}
贡献者
freeway348