花匠

这是noip的一道动态规划题目,这里分享两种做法


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];


```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值