初看这道题想到O(n2) 的暴力dp

用f[i][0]表示取第i个点为最低点时的答案, f[i][1]为最高点,且f[i][0] = max( f[j][1] ) +1

这样每次都要查询前面区间满足 h[i]>h[j] 的最大值, 可以考虑 线段树区间查询 或者 BIT 或者BST , 时间降至O(nlogn)

但是BIT时要注意查询h[i]<h[j] 条件时涉及到 j ~ maxheight 的最值查询, 可以把maxheight -h[i] +2 (BIT下标不为0) 存入树状数组

RE 代码:BIT 误取最大下标为n!! 实际上应该在读入时求出maxheight!!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define lowbit(x) x&-x
#define smax(x,tmp) x=max(x,tmp)
const int maxn=100005;
const int INF=0x3f3f3f3f;
int high[maxn],low[maxn];//!! LAST RE!!! BIT  must be bigger!! maxheight!!!
int f[maxn][2];//0: low point ; 1: high point
int a[maxn];
int n;
int maxheight=-INF;
inline void add_low(int x,int val)
{for(int i=x;i<=maxheight+1;i+=lowbit(i)) smax(low[i],val);//also easy to consider as n!!
}
inline void add_high(int x,int val)
{for(int i=x;i<=maxheight+1;i+=lowbit(i)) smax(high[i],val);
}
inline int query_low(int x)
{int ret=0;for(int i=x;i;i-=lowbit(i))    smax(ret,low[i]);return ret;
}
inline int query_high(int x)
{int ret=0;for(int i=x;i;i-=lowbit(i)) smax(ret,high[i]);return ret;
}int main()
{freopen("flower.in","r",stdin);freopen("flower.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",a+i),smax(maxheight,a[i]);int ans=1;f[1][0]=f[1][1]=1;add_low(a[1]+1,f[1][0]);add_high(maxheight-a[1]+2,f[1][1]);//add reversely, to query the max !!for(int i=2;i<=n;i++){f[i][0]=query_high(maxheight-a[i]+1)+1;f[i][1]=query_low(a[i])+1;add_low(a[i]+1,f[i][0]);//can't either!!add_high(maxheight-a[i]+2,f[i][1]);// mustn't use the 0 point !!smax(ans,max(f[i][0],f[i][1]));}printf("%d",ans);return 0;
}

View Code

AC代码:(BIT)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define lowbit(x) x&-x
#define smax(x,tmp) x=max(x,tmp)
const int maxn=100005;
const int maxh=1000005;
const int INF=0x3f3f3f3f;
int high[maxh],low[maxh];//for BIT
int f[maxn][2];//0: low point ; 1: high point
int a[maxn];
int n;
int maxheight=-INF;
inline void add_low(int x,int val)
{for(int i=x;i<=maxheight+1;i+=lowbit(i)) smax(low[i],val);
}
inline void add_high(int x,int val)
{for(int i=x;i<=maxheight+1;i+=lowbit(i)) smax(high[i],val);
}
inline int query_low(int x)
{int ret=0;for(int i=x;i;i-=lowbit(i))    smax(ret,low[i]);return ret;
}
inline int query_high(int x)
{int ret=0;for(int i=x;i;i-=lowbit(i)) smax(ret,high[i]);return ret;
}int main()
{freopen("flower.in","r",stdin);freopen("flower.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",a+i),smax(maxheight,a[i]);int ans=1;f[1][0]=f[1][1]=1;add_low(a[1]+1,f[1][0]);add_high(maxheight-a[1]+2,f[1][1]);//add reversely, to query the max !!for(int i=2;i<=n;i++){f[i][0]=query_high(maxheight-a[i]+1)+1;f[i][1]=query_low(a[i])+1;add_low(a[i]+1,f[i][0]);//can't either!!add_high(maxheight-a[i]+2,f[i][1]);// mustn't use the 0 point !!smax(ans,max(f[i][0],f[i][1]));}printf("%d",ans);return 0;
}//O(n): f[i][0,1] indicates that don't need to stop at i, but had the previous cases//O(n): find the corners with the tendency

View Code

现虑另一种 O(n) 的dp

用f[i][0,1] 表示 i 及其以前所有高度的最大值,但是0 表示之前出于下降阶段而并非之前的上一个节点为转折点, 仅仅表示一个趋势

另一种 o(n) 算法

由于一段相同变化趋势的区段内只能留下一个端点

故只需要统计出所有的”拐点“即可!

WA代码: 只考虑到相邻的几个数,但是缺乏长远的考虑!!!!应用趋势来判断!!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define lowbit(x) x&-x
#define smax(x,tmp) x=max(x,tmp)
const int maxn=100005;
const int INF=0x3f3f3f3f;
int n;
int a[maxn];
int main()
{freopen("flower.in","r",stdin);freopen("flower.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",a+i);int ans=2;for(int i=2;i^n;i++){if(a[i-1]>a[i] && a[i]<a[i+1]) ans++;//Last WA!! not only the near one, but long tremsif(a[i-1]<a[i] && a[i]>a[i+1]) ans++;}printf("%d",ans);return 0;
}

View Code

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define lowbit(x) x&-x
#define smax(x,tmp) x=max(x,tmp)
const int maxn=100005;
const int INF=0x3f3f3f3f;
int n;
int a[maxn];
int main()
{freopen("flower.in","r",stdin);freopen("flower.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",a+i);int ans=1;//indicates the first one to start!!int flag=0;//indicates start!!for(int i=1;i^n;i++){if(a[i]<a[i+1] && (flag==0 || flag==-1)) flag=1,ans++;if(a[i]>a[i+1] && (flag==0 || flag==1)) flag=-1,ans++;}printf("%d",ans);return 0;
}

View Code

转载于:https://www.cnblogs.com/ourfutr2330/p/5665054.html

[NOIP2013] 花匠相关推荐

  1. Luogu 1970 NOIP2013 花匠 (贪心)

    Luogu 1970 NOIP2013 花匠 (贪心) Description 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使 ...

  2. [NOIP2013]花匠

    [NOIP2013]花匠 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希望剩下的花排列得比 ...

  3. NOIP2013 花匠解题报告

    //<NOIP2013> 花匠 /*最优子结构性质,可以用动规.注意到存在30%的变态数据(1 ≤ n ≤ 100,000,0 ≤ h_i ≤1,000,000),因此应当找到线性的算法. ...

  4. NOIP2013 花匠 题解(方法全面)

    2.花匠 (flower.cpp/c/pas) [问题描述] 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间 ...

  5. Noip2013花匠

    考试的时候想到了正确算法然而因为种种细节错误只有40分... 简单思路:找转折点.(在处理的时候,假如一开始序列是逆着的,我们默认开头是一个转折点)虽然这不一定是唯一解,但一定是可行的最优解. 当然我 ...

  6. noip2017考前整理(未完)

    快考试了,把我以前写过的题回顾一下. Noip2007 树网的核:floyd,推出性质,暴力. Noip2008 笨小猴:模拟 Noip2008 火柴棒等式:枚举 Noip2008 传纸条:棋盘dp ...

  7. OI 刷题记录——每周更新

    每周日更新 2016.05.29 UVa中国麻将(Chinese Mahjong,Uva 11210) UVa新汉诺塔问题(A Different Task,Uva 10795) NOIP2012同余 ...

  8. [vijos1571] 笨笨的导弹攻击

    题目链接 题解:和noip2013花匠很像,记录下奇偶即可 #include <iostream> #include <cstdio> using namespace std; ...

  9. 【NOIP2013提高组】花匠

    题目背景 NOIP2013 提高组 Day2 试题. 题目描述 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空 ...

最新文章

  1. Spring4 MVC文件下载实例
  2. Hangfire在ASP.NET CORE中的简单实现
  3. 轻松部署IE7(下),SMS2003系列之六
  4. php攻击方式及防御方法,Syn Flood 攻击 及其一般防御方法
  5. cisco交换机命令大全(10)
  6. C++ Primer 第三章 标准库类型 笔记
  7. 拜耳2020年10个新植保制剂商业化,3个生物技术性状项目推进至上市阶段
  8. 【Visual C++】游戏开发笔记十四 游戏画面绘图(四) 华丽的CImage类
  9. 将靠父id的层级关系处理成编码形式
  10. 基于深度学习的Depth and Ego-Motion Estimation
  11. python打开setting_Python3 - setting的默认配置和用户配置读取
  12. icarus主题的博客加载太慢
  13. 自学考试-“软件开发工具”
  14. 在web上制作动画(css3)
  15. Serializable的含义
  16. 客户端访问网站的整个流程图_如何阻止整个国家访问您的网站
  17. 《基于Cortex-M4的ucOS-III的应用》课程设计 结题报告
  18. 计算机视觉与摄影测量
  19. 从多个维度说说产品经理的分类与发展方向
  20. jiny的博客开通啦~~

热门文章

  1. sap ABAP中常用函数
  2. Oracle 11g Release 1 (11.1) Oracle 本文索引的四种类型
  3. ​CVPR2021最佳学生论文提名:Less is More
  4. 深圳 | 腾讯 Robotics X 招聘语义视觉方向实习生和正式员工
  5. 用Python把github上非常实用的数据全部抓取下来! 留给自己备用
  6. Android开发继承webview,WebView如何从当前的Android主题继承颜色?
  7. linux监控mysql性能,MySQL 性能监控4大指标——第二部分
  8. 收藏 | Python数据分析必备速查表
  9. 怎样改变计算机桌面的特效主题,电脑桌面主题、图片怎么设置的技巧大全
  10. 紫光展锐【软件工程师】面经