「Luogu P3078 [USACO13MAR]扑克牌型Poker Hands」
本题有\(O(N)\)的优秀做法,但是因为在考场上不一定能想到,就来分享一种\(O(N\log_2N)\)的做法.虽然有点慢,但是可以过.
前置芝士
具体做法
只要会线段树就珂以了,是不是很简单.
先考虑贪心,连续的一定是一次去掉,不可能分成多次去取.

于是答案就是每一行连续的段数之和.
如图,第一行为\(1\)段,第二行\(2\)段,第三行\(2\)段,第四行为\(1\)段,所以答案就是\(1+2+2+1=6\).然后再考虑怎么去算出每一行的段数,如果暴力去求肯定是会T的需要\(O(N^2)\)的时间复杂度,好像也没有什么其他的快速求法,于是再考虑分治,没一次将最下方的若干个完整的一行去掉后就将问题分为若干个子问题,暴力的方法就可以跑过更多的点了,但还是可能被一些特殊的数据卡掉.

如这样一个数据,每一次查找当前区间最低的高度需要\(O(N)\)的时间复杂度,最终的时间复杂度就会退化成\(O(N^2)\).于是可以用线段树优化.时间复杂度就是\(O(N\log_2N)\)(大概).
代码
#include<bits/stdc++.h>
#define rap(i,first,last) for(int i=first;i<=last;++i)
//线段树标准define
#define Lson (now<<1)
#define Rson (now<<1|1)
#define Middle ((left+right)>>1)
#define Left Lson,left,Middle
#define Right Rson,Middle+1,right
#define Now nowleft,nowright
using namespace std;
const int maxN=5e5+7;
const int INF=123123123;//一个极大值
int N;
int tree[maxN*4];
int arr[maxN];
void PushUp(int now)//查询区间最大值
{
tree[now]=min(tree[Lson],tree[Rson]);
}
void Build(int now=1,int left=1,int right=N)//建树
{
if(left==right)
{
tree[now]=arr[left];
return;
}
Build(Left);
Build(Right);
PushUp(now);
}
//不需要修改
int Query(int nowleft,int nowright,int now=1,int left=1,int right=N)//查询区间最小值
{
if(right<nowleft||nowright<left)return INF;
if(nowleft<=left&&right<=nowright)
{
return tree[now];
}
return min(Query(Now,Left),Query(Now,Right));
}
int QueryPlace(int nowleft,int nowright,int m,int now=1,int left=1,int right=N)
//查询区间下一个最小值的位置,m为最小值
{
if(right<nowleft||nowright<left)return INF;
if(left==right)
{
if(tree[now]==m)
return left;
return INF;
}
int result=INF;
if(tree[Lson]<=m)//如果左区间可能存在就先查找左区间
{
result=QueryPlace(Now,m,Left);
}
if(result!=INF)return result;//存在就返回
return QueryPlace(Now,m,Right);//不存在查找右区间
}
long long get(int l,int r/*当前的区间*/,int delhigh/*当前减去的高度*/)
{
if(l>r)return 0;
if(l==r)return arr[l]-delhigh;//l=r时就为当前剩余高度
int minhigh=Query(l,r);
int now=l-1,place;
if(arr[l]==minhigh)now++;//为了防止陷入死循环
long long result=(minhigh-delhigh);//先将最下方可以取的部分直接取掉
while(1)//通过线段树将每一段区间找出并继续加上答案
{
place=QueryPlace(now+1,r,minhigh);
if(place==INF)break;//如果没有下一个位置就退出
result+=get(now+1,place-1,minhigh);//有就加上答案
now=place;
}
if(arr[r]==minhigh)//为了防止陷入死循环
result+=get(now+1,r-1,minhigh);
else
result+=get(now+1,r,minhigh);
return result;//返回答案
}
int main()
{
scanf("%d",&N);//读入
rap(i,1,N)
scanf("%d",&arr[i]);
Build();//建树
printf("%lld\n",get(1,N,0));//输出
return 0;
}
「Luogu P3078 [USACO13MAR]扑克牌型Poker Hands」的更多相关文章
- 洛谷 P3078 [USACO13MAR]扑克牌型Poker Hands
P3078 [USACO13MAR]扑克牌型Poker Hands 题目描述 Bessie and her friends are playing a unique version of poker ...
- 洛谷P3078 [USACO13MAR]扑克牌型Poker Hands
题目描述 Bessie and her friends are playing a unique version of poker involving a deck with \(N\) (\(1 \ ...
- P3078 [USACO13MAR]扑克牌型Poker Hands
题目描述 Bessie and her friends are playing a unique version of poker involving a deck with N (1 <= N ...
- 【贪心 思维题】[USACO13MAR]扑克牌型Poker Hands
看似区间数据结构的一道题 题目描述 Bessie and her friends are playing a unique version of poker involving a deck with ...
- 「Luogu P2468 [SDOI2010]粟粟的书架」
这道题分为两个部分 Part1 前置芝士 前缀和(后缀和,二维前缀和):可以预处理一下数据. 二分查找:可以在较短的时间内找出答案. 具体做法 可以发现\(R,C\)不大,只有\(200\),于是可以 ...
- 「Luogu P3820 小D的地下温泉」
这道题的考点比较多. 前置芝士 BFS(DFS),这两种算法在这道题中并没有什么特别突出的地方,基本就是自己看心情写(本文以DFS为准,所以我心情是好是坏呢?) 连通块,可以将每一个温泉看作一个连通块 ...
- 「Luogu P2253 好一个一中腰鼓!」
就这道题的理论难度来说绿题是有点低了,但是这道题的实际难度来看,顶多黄题,所以建议加强数据或出数据升级版. 前置芝士 线段树:具体可以看我的另一篇文章. 具体做法 暴力的方法想必都会,所以来讲一下正解 ...
- 使用ML.NET实现德州扑克牌型分类器
导读:ML.NET系列文章 本文将基于ML.NET v0.2预览版,重点介绍提取特征的思路和方法,实现德州扑克牌型分类器. 先介绍一下德州扑克的基本牌型,一手完整的牌共有五张扑克,10种牌型分别是: ...
- 每个男孩的机械梦「GitHub 热点速览 v.21.41」
作者:HelloGitHub-小鱼干 机械臂可能在医疗剧中看过,可以用来执行一些精细化的操作,例如:缝合之类的.但这次 Dummy-Robot 让你不仅看看而已,还具备一定的实操性(有一定的动手.经济 ...
随机推荐
- keil(MDK)错误记录
1.a parameter list without types is only allowed in a function definition(没有类型的参数列表只允许在函数定义中使用) 2.Er ...
- PTA的Python练习题(十八)
第4章-20 求矩阵各行元素之和 遇到一个麻烦的事情: 上面a,b输入,如果一起输入转int会报错,因为int只能一对一 但是明明我分开来int了,下面第十行还是报错说我的b是string字符,难不成 ...
- 存储引擎,MySQL中的数据类型及约束
存储引擎,MySQL中的数据类型及约束 一.存储引擎 1.不同的数据应该有不同的处理机制 2.mysql存储引擎 Innodb:默认的存储引擎,查询速度叫myisam慢,但是更安全 支持事务, ...
- 拥抱高通的联想,真的能靠5G突围?
编辑 | 于斌 出品 | 于见(mpyujian) 2016年,对于常年自我标榜为"民族企业"的联想来说是品牌口碑的"转折之年".它在这一年的5G信道编码标准方 ...
- Shiro入门学习之shi.ini实现授权(三)
一.Shiro授权 前提:需要认证通过才会有授权一说 1.授权过程 2.相关方法说明 ①subject.hasRole("role1"):判断是否有该角色 ②subject.has ...
- Python使用Tensorflow出现错误: UserWarning: The default mode, 'constant'
Python使用Tensorflow出现错误: UserWarning: The default mode, 'constant', will be changed to 'reflect' in s ...
- linux 开启普通用户sudo root权限操作获取免密
root 身份登陆 $ visudo然后进入修改配置找到 root ALL=(ALL) ALL 在下面增加: yourusername ALL=(ALL) NOPASSWD: ALL ex ...
- 让你的逼格瞬间提升的十个Python语法!
Python 是一种代表简单思想的语言,其语法相对简单,很容易上手.不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了.本文精心筛选了最能展现 Python 语法之精妙的十个知识点,并 ...
- 使刚编辑的vim编辑器配置文件立即生效(实为自动生效)
简单的说,在虚拟机下安装的Centos6.3系统后,默认的是没有vim编辑器的配置文件,此时如果有必要,可以按照自己的习惯定制或配置自己的vim编辑器: 1,如果你是root权限,进入root目录下: ...
- 说明与比较:new Vue() 和 export default {}
在生成.导出.导入.使用 Vue 组件的时候,像我这种新手就会常常被位于不同文件的 new Vue() 和 export default{}.它们含义到底是什么,又有什么异同呢? 首先,Vue 是什么 ...