这是noip的一道动态规划题目,这里分享两种做法
1.贪心
根据题意,要满足的条件是任意三个连续的数中中间的数是最大或最小的,我的想法是枚举出所有单调性改变的地方,从这里选数
对于递增序列,我们要选的数要比当前的小,所以我们让现在这个数尽量大,下面这个数可选择的方式越多(语文不好,,顺便吐槽一下月考语文答题卡竟让没过,,),递减序列同理
对于第一盆花,如果我们不选,第二盆花就成了第一盆,花的总数减少了,所以一定不会更优,故ans=1
我们继续向下选,若第二盆花与第一盆花等高,则pass。如果比第一盆高,那它就是是一个极大值(如果是极小值则认为第一盆没选);
同理如果第二盆花比第一盆低那就一定是极小值
在后面的花中,找极大值,那么当前花比上一盆高,然后去找极小值;如果不如上一盆高,那么用这盆花找极大值结果一定不会更差
找极小值同理
附代码
```cpp
```
二.动态规通过观察题面可以发现递推关系
于是可以用两个数组分别记录到i下降和到i上升
容易得出递推公式
```cpp
```
1.贪心
根据题意,要满足的条件是任意三个连续的数中中间的数是最大或最小的,我的想法是枚举出所有单调性改变的地方,从这里选数
对于递增序列,我们要选的数要比当前的小,所以我们让现在这个数尽量大,下面这个数可选择的方式越多(语文不好,,顺便吐槽一下月考语文答题卡竟让没过,,),递减序列同理
对于第一盆花,如果我们不选,第二盆花就成了第一盆,花的总数减少了,所以一定不会更优,故ans=1
我们继续向下选,若第二盆花与第一盆花等高,则pass。如果比第一盆高,那它就是是一个极大值(如果是极小值则认为第一盆没选);
同理如果第二盆花比第一盆低那就一定是极小值
在后面的花中,找极大值,那么当前花比上一盆高,然后去找极小值;如果不如上一盆高,那么用这盆花找极大值结果一定不会更差
找极小值同理
附代码
```cpp
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
int l=1,r=1;
int main()
{
int last_h,now_h;
int dandiao=-1,ans=1;
cin>>n>>last_h;
for(int i=2;i<=n;i++)
{
cin>>now_h;
//if(now_h>last_h) r=max(r,l+1);
//if(now_h<last_h) l=max(l,r+1);
if((now_h>last_h)&&((dandiao==-1)||(dandiao==0)))
{
ans++;
dandiao=1;
}
if((now_h<last_h)&&((dandiao==-1)||(dandiao==1)))
{
ans++;
dandiao=0;
}
last_h=now_h;
}
//cout<<max(l,r)<<endl;
cout<<ans<<endl;
return 0;
}
```
二.动态规通过观察题面可以发现递推关系
于是可以用两个数组分别记录到i下降和到i上升
容易得出递推公式
```cpp
if(a[i]>a[i-1])f[i][0]=f[i-1][1]+1;
else f[i][0]=f[i-1][0];
if(a[i]<a[i-1])f[i][1]=f[i-1][0]+1;
else f[i][1]=f[i-1][1];
```