传送门

n2 过不了惨啊

70分做法

f[i][0] 表示第 i 个作为高的,的最优解

f[i][0] 表示第 i 个作为低的,的最优解

(且第 i 个一定选)

那么

f[i+1][1]=max(f[j][0])+1,i>=j>=1,h[j]>h[i+1],

f[i+1][0]=max(f[j][1])+1,i>=j>=1,h[j]<h[i+1],

——代码

 #include <cstdio>
#include <algorithm> const int MAXN = , INF = ~( << );
int n, ans, max;
int a[MAXN], f[MAXN][]; inline int Max(int x, int y)
{
return x > y ? x : y;
} int main()
{
//freopen("flower.in", "r", stdin);
//freopen("flower.out", "w", stdout);
int i, j;
scanf("%d", &n);
for(i = ; i <= n; i++) scanf("%d", &a[i]);
for(i = ; i <= n; i++)
{
max = ;
for(j = ; j < i; j++)
if(a[j] < a[i] && f[j][] > max)
max = f[j][];
f[i][] = max + ;
ans = Max(ans, f[i][]);
max = ;
for(j = ; j < i; j++)
if(a[j] > a[i] && f[j][] > max)
max = f[j][];
f[i][] = max + ;
ans = Max(ans, f[i][]);
}
printf("%d\n", ans);
return ;
}

100分

我们发现上面的方程可以用线段树优化,可以建一颗权值线段树

 #include <cstdio>
#include <iostream>
#include <algorithm>
#define root 1, 1, size
#define ls now << 1, l, mid
#define rs now << 1 | 1, mid + 1, r const int MAXN = ;
int n, size;
int a[MAXN], b[MAXN], f[MAXN][], max[MAXN << ][]; inline int read()
{
int x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline int Max(int x, int y)
{
return x > y ? x : y;
} inline void pushup(int now)
{
max[now][] = Max(max[now][], max[now << ][]);
max[now][] = Max(max[now][], max[now << | ][]);
max[now][] = Max(max[now][], max[now << ][]);
max[now][] = Max(max[now][], max[now << | ][]);
} inline int query(int x, int y, int k, int now, int l, int r)
{
if(x <= l && r <= y) return max[now][k];
int mid = (l + r) >> ;
if(l > y || r < x) return ;
return Max(query(x, y, k, ls), query(x, y, k, rs));
} inline void update(int x, int a, int b, int now, int l, int r)
{
if(l == r)
{
max[now][] = Max(max[now][], a);
max[now][] = Max(max[now][], b);
return;
}
int mid = (l + r) >> ;
if(x <= mid) update(x, a, b, ls);
else update(x, a, b, rs);
pushup(now);
} int main()
{
int i;
n = read();
for(i = ; i <= n; i++) a[i] = b[i] = read();
std::sort(b + , b + n + );
size = std::unique(b + , b + n + ) - (b + );
for(i = ; i <= n; i++) a[i] = std::lower_bound(b + , b + size + , a[i]) - b;
for(i = ; i <= n; i++)
{
f[i][] = query(, a[i] - , , root) + ;
f[i][] = query(a[i] + , size, , root) + ;
update(a[i], f[i][], f[i][], root);
}
printf("%d\n", Max(f[n][], f[n][]));
return ;
}

100分

用个p线段树,树状数组维护前后缀就好。

 #include <cstdio>
#include <iostream>
#include <algorithm>
#define root 1, 1, size
#define ls now << 1, l, mid
#define rs now << 1 | 1, mid + 1, r const int MAXN = ;
int n, ans;
int c0[MAXN], c1[MAXN]; inline int read()
{
int x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline int max(int x, int y)
{
return x > y ? x : y;
} inline int query1(int x)
{
int ret = ;
for(; x <= MAXN; x += x & -x) ret = max(ret, c1[x]);
return ret;
} inline int query0(int x)
{
int ret = ;
for(; x; x -= x & -x) ret = max(ret, c0[x]);
return ret;
} inline void update0(int x, int d)
{
for(; x <= MAXN; x += x & -x) c0[x] = max(c0[x], d);
} inline void update1(int x, int d)
{
for(; x; x -= x & -x) c1[x] = max(c1[x], d);
} int main()
{
int i, x, y, z;
n = read();
for(i = ; i <= n; i++)
{
z = read() + ;
x = query1(z + ) + ;
y = query0(z - ) + ;
update0(z, x);
update1(z, y);
ans = max(ans, max(x, y));
}
printf("%d\n", ans);
return ;
}

100分

f[i][0] 表示第 i 个作为高的,的最优解

f[i][0] 表示第 i 个作为低的,的最优解

(然而第 i 个不一定选)

那么

h[i]>h[i−1]时,

f[i][0]=max{f[i−1][0],f[i−1][1]+1},f[i][1]=f[i−1][1];

h[i]==h[i−1]时,

f[i][0]=f[i−1][0],f[i][1]=f[i−1][1];

h[i]<h[i−1]时,

f[i][0]=f[i−1][0],f[i][1]=max{f[i−1][1],f[i−1][0]+1}.

答案ans=max{f[n][0],f[n][1]};

边界为f[1][0]=f[1][1]=1

——代码

 #include <cstdio>
#include <algorithm> const int MAXN = , INF = ~( << );
int n, ans;
int a[MAXN], f[MAXN][]; inline int max(int x, int y)
{
return x > y ? x : y;
} int main()
{
//freopen("flower.in", "r", stdin);
//freopen("flower.out", "w", stdout);
int i, j;
scanf("%d", &n);
for(i = ; i <= n; i++) scanf("%d", &a[i]);
f[][] = f[][] = ;
for(i = ; i <= n; i++)
{
if(a[i] > a[i - ])
{
f[i][] = max(f[i - ][], f[i - ][] + );
f[i][] = f[i - ][];
}
else if(a[i] == a[i - ])
{
f[i][] = f[i - ][];
f[i][] = f[i - ][];
}
else
{
f[i][] = f[i - ][];
f[i][] = max(f[i - ][], f[i - ][] + );
}
}
printf("%d\n", max(f[n][], f[n][]));
return ;
}

[luoguP1970] 花匠(DP)的更多相关文章

  1. 洛谷 P1970 花匠 —— DP

    题目:https://www.luogu.org/problemnew/show/P1970 普通的DP,f[i][0/1] 表示 i 处处于较小或较大的长度: 注意:1.树状数组向后 query 时 ...

  2. $Noip2013/Luogu1970$ 花匠 $dp$+思维

    $Luogu$ $Sol$ 和$Poj1037\ A\ Decorative\ Fence$好像吖. $f[i][0/1]$表示前$i$个数,且选了第$i$个数,这个数相对于上一个数是下降(上升)的, ...

  3. NOIP2013 花匠 DP 线段树优化

    网上一堆题解,我写的是N^2优化的那种,nlogn,O(n)的那种能看懂,但是让我自己在赛场写,肯定没戏了 #include <cstdio> #include <iostream& ...

  4. luogu1970 花匠(dp)

    设f1[i]表示以1..i中某个合法序列的长度,而且最后一位是较大的 f2[i]表示以1..i中某个合法序列的长度,而且最后一位是较小的 那么就有$f1[i]=max\{f2[j]+1\},(j< ...

  5. 洛谷P1970 花匠(dp)

    题意 题目链接 Sol 直接用\(f[i][0/1]\)表示到第\(i\)个位置,该位置是以上升结尾还是以下降结尾 转移的时候只需枚举前一个即可 #include<cstdio> #inc ...

  6. NOIP2013 提高组合集

    NOIP 2013 提高组 合集 D1 T1 转圈游戏 快速幂裸题 #include <iostream> #include <cstdio> #include <cst ...

  7. $NOIp$提高组历年题目复习

    写在前面 一个简略的\(NOIp\)题高组历年题目复习记录.大部分都有单独写题解,但懒得放\(link\)了\(QwQ\).对于想的时候兜了圈子的题打上\(*\). \(NOIp2018\ [4/6] ...

  8. DP练习题——洛谷P1970花匠

    目录 题目描述: 输入输出格式: 输入格式: 输出格式: 输入输出样例: 输入样例: 输出样例: 题目分析: 解法一: 解法二: 结语: 题目描述: 洛谷\(P1970\) 花匠栋栋种了一排花,每株花 ...

  9. [DP][NOIP2013]花匠

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

随机推荐

  1. Magento Order 状态详解

    流程图:

  2. Windows查杀端口

    Windows环境下当某个端口被占用时,通过netstat命令进行查询pid,然后通过taskkill命令杀进程. 一.查询占用端口号的进程信息 netstat -an|findstr 二.杀掉占用端 ...

  3. 转 SQL - 字符串中的转义字符

    一位同事在使用SQL处理一串字符时,出现一个意料之外的问题:这个字符串中包括字符‘&’.我们先看一下现象:     SQL> select * from v$version;     B ...

  4. 关于OPPO手机的生存和程序员的发展

    关于程序员私下讨论最多的话题,除了哪个编程最牛逼之外,哪款品牌的手机最牛逼也是我们谈论最多的话题之一吧!有的喜欢罗永浩,自然就是锤粉:有的喜欢苹果,称它为工业时代最优美的艺术品:当然,我想也有很多的人 ...

  5. Java8-Lomda表达式

    Lomda表达式 /** * All rights Reserved, Designed By www.bingo.com * @Title TestLamda.java * @author yang ...

  6. java课程设计全程实录——第1天

    反思,总结昨天: IDE搭建完成: git远程配置失败,处理方式:放弃使用git 主要参考<疯狂java实战演义>中的图书进销存管理系统.但该项目是MySQL,无法直接套用,因为我们学的是 ...

  7. svn 使用手册

    版本控制器:SVN 1 开发中的实际问题 1.1 小明负责的模块就要完成了,就在即将Release之前的一瞬间,电脑突然蓝屏,硬盘光荣牺牲!几个月来的努力付之东流——需求之一:备份! 1.2 这个项目 ...

  8. Node.js(二)常用的系统模块

    http模块 第一章已经介绍了 node.js 的模块都可以传一个回调函数  回调函数支持两个参数  error , data let fs = require('fs'); fs.readFile( ...

  9. YOLOv3模型识别车位图片的测试报告(节选)

    1,YOLOv3模型简介 YOLO能实现图像或视频中物体的快速识别.在相同的识别类别范围和识别准确率条件下,YOLO识别速度最快. 官网:https://pjreddie.com/darknet/yo ...

  10. 详解java中staitc关键字

    一.static定义 static是静态修饰符意思,什么叫静态修饰符呢?大家都知道,在程序中任何变量或者代码都是在编译时由系统自动分配内存来存储的,而所谓静态就是指在编译后所分配的内存会一直存在,直到 ...