汉诺塔(思维、DP思想)
链接:https://ac.nowcoder.com/acm/contest/3007/C
来源:牛客网
题目描述
输入描述:
输出描述:
输入
输出
最长上升子序列的 贪心+二分法:O(nlogn)
分析:要让一个序列具有最长上升子序列,其实就是保证子序列中的每个元素尽可能小,降低门槛,让后面的元素尽可能多进入该子序列
实现:定义一个最长子序列数组Array,以及当前长度Len,从头到尾维护数组a
a. a[i]>Array[i] (当前元素大于子序列结尾元素),则a[i]进入子序列:Array[++len] = a[i]
b. a[i]<=Array[i],这时对Array进行维护,把Array中比a[i]大的第一个元素替换成a[i](这样可以降低后面元素进入子序列的门槛。
c. 为了降低算法复杂度,因为Array是升序序列,所以用lower_bound查找Array中第一个大于等于a[i]的元素
官方题解:
这题跟以前一道dp题导弹拦截问题很像。
求最长下降子序列长度+二分
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
const int INF=0x3f3f3f3f;
typedef long long LL;
const double eps =1e-;
const int mod=1e9+;
const int maxn=1e5+;
using namespace std; struct node
{
int x,y;
int id;
bool operator <(const node &a) const//小到大
{
return x<a.x;
}
}P[maxn]; int fa[maxn],st[maxn];
int cnt; int main()
{
#ifdef DEBUG
freopen("sample.txt","r",stdin);
#endif int n;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d %d",&P[i].x,&P[i].y);
P[i].id=i;
}
sort(P+,P++n);
int cnt=;
for(int i=;i<=n;i++)
{
int L=,R=cnt;
while(L<=R)//二分查找st中第一个比P[i].y小的位置
{
int mid=(L+R)>>;
if(st[mid]<P[i].y)
R=mid-;
else if(st[mid]>P[i].y) L=mid+;
}
st[L]=P[i].y;//替换该位置的值(贪心)
if(L>cnt) cnt=L;//比st中所有都小,添到尾部
fa[P[i].id]=L;//它替换了st中谁的值,他就跟谁在同一个集合
}
printf("%d\n",cnt);
for(int i=;i<=n;i++)
printf(i==n?"%d\n":"%d ",fa[i]); return ;
}
求最长上升子序列长度+upper_bound()
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
const int INF=0x3f3f3f3f;
typedef long long LL;
const double eps =1e-;
const int mod=1e9+;
const int maxn=1e5+;
using namespace std; struct node
{
int x,y;
int id;
bool operator <(const node &a) const//大到小
{
return x>a.x;
}
}P[maxn]; int fa[maxn],st[maxn];
int cnt; int main()
{
#ifdef DEBUG
freopen("sample.txt","r",stdin);
#endif int n;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d %d",&P[i].x,&P[i].y);
P[i].id=i;
}
sort(P+,P++n);
int cnt=;
for(int i=;i<=n;i++)
{
int pos;
if(P[i].y>st[cnt]) pos=++cnt;//比st中所有都大,添到尾部
else pos=upper_bound(st+,st++cnt,P[i].y)-(st+)+;//下标别忘加1
st[pos]=P[i].y;//替换该位置的值(贪心)
fa[P[i].id]=pos;//它替换了st中谁的值,他就跟谁在同一个集合
}
printf("%d\n",cnt);
for(int i=;i<=n;i++)
printf(i==n?"%d\n":"%d ",fa[i]); return ;
}
-
汉诺塔(思维、DP思想)的更多相关文章
- hdu 1207 汉诺塔II (DP+递推)
汉诺塔II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- BZOJ_1019_[SHOI2008]_汉诺塔_(DP)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1019 汉诺塔游戏,但是有移动优先级,在不违反原有规则的情况下,给定优先移动目标.求完成游戏所需 ...
- 【BZOJ 1019】 1019: [SHOI2008]汉诺塔 (DP?)
1019: [SHOI2008]汉诺塔 Description 汉诺塔由三根柱子(分别用A B C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一 ...
- 【ACwing 96】奇怪的汉诺塔——区间dp
(题面来自ACwing) 汉诺塔问题,条件如下: 1.这里有A.B.C和D四座塔. 2.这里有n个圆盘,n的数量是恒定的. 3.每个圆盘的尺寸都不相同. 4.所有的圆盘在开始时都堆叠在塔A上,且圆盘尺 ...
- 2020牛客寒假算法基础集训营6 C 汉诺塔 (dp 最长下降子序列)
https://ac.nowcoder.com/acm/contest/3007/C 将木板按照Xi从小到大排序,将这时的Yi数列记为Zi数列,则问题变成将Zi划分为尽可能少的若干组上升子序列. 根据 ...
- C语言数据结构----递归的应用(斐波拉契数列、汉诺塔、strlen的递归算法)
本节主要说了递归的设计和算法实现,以及递归的基本例程斐波拉契数列.strlen的递归解法.汉诺塔和全排列递归算法. 一.递归的设计和实现 1.递归从实质上是一种数学的解决问题的思维,是一种分而治之的思 ...
- 四柱加强版汉诺塔HanoiTower----是甜蜜还是烦恼
我想很多人第一次学习递归的时候,老师或者书本上可能会举汉诺塔的例子. 但是今天,我们讨论的重点不是简单的汉诺塔算法,而是三柱汉诺塔的延伸.先来看看经典的三柱汉诺塔. 一.三柱汉诺塔(Hanoi_Thr ...
- 汉诺塔 Hanoi Tower
电影<猩球崛起>刚开始的时候,年轻的Caesar在玩一种很有意思的游戏,就是汉诺塔...... 汉诺塔源自一个古老的印度传说:在世界的中心贝拿勒斯的圣庙里,一块黄铜板上插着三支宝石针.印度 ...
- NOI-OJ 2.2 ID:6261 汉诺塔
思路 汉诺塔是递归思想最经典的例子,通过递归不断缩小问题,将n个盘子的问题简化n-1个,直至1个. 三个盘子,分别为A:from,B:to,C:by(A为起点盘,B为目标盘,C为中转盘) 过程 将1- ...
- [递推]B. 【例题2】奇怪汉诺塔
B . [ 例 题 2 ] 奇 怪 汉 诺 塔 B. [例题2]奇怪汉诺塔 B.[例题2]奇怪汉诺塔 题目描述 汉诺塔问题,条件如下: 这里有 A A A. B B B. C C C 和 D D D ...
随机推荐
- 白手起家Django项目发布上篇_linux centos 环境部署
在项目发布之前,首先准备好我们编写好的Django项目,这个我们在之后博客有写,大家可以去看, 首先,先开始安装linux服务器,作为Django项目的发布服务器.以Vmware虚拟机为例子,大家也可 ...
- 并行执行 Job【转】
有时,我们希望能同时运行多个 Pod,提高 Job 的执行效率.这个可以通过 parallelism 设置. 这里我们将并行的 Pod 数量设置为 2,实践一下: Job 一共启动了两个 Pod,而且 ...
- brew services start redis 无法使用问题排查
起因 Mac上使用brew services start --all指令同时启动多个服务显示成功 但是,连接四个服务所在端口均无响应. 仔细核对过brew指令启动服务使用的路径.配置文件路径均无问题. ...
- RAID与磁盘管理之——综合应用
为了实现磁盘的管理和RAID的综合,现将四块硬盘组合成一个RAID10,并在此基础之上创建物理卷.卷组.逻辑卷,实现在线扩容,最后挂载使用. 其中也部分包含了swap分区的创建和使用. 1.根据lin ...
- 17. Getting to the essence of things
17.Getting to the essence of things.抓住事情的本质 From today on, I think I should keep a diary. To the CCU ...
- haproxy+keepalive双主高可用实现负载均衡
转载自https://blog.51cto.com/3381847248/1977073 前面我已经介绍了haproxy结合keepalive做简单的双主高可用,如果不清楚的话,可以去我的上一 篇博客 ...
- 039、Java中逻辑运算之普通与运算“&”
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- 13.在项目中部署redis企业级数据备份方案以及各种踩坑的数据恢复容灾演练
到这里为止,其实还是停留在简单学习知识的程度,学会了redis的持久化的原理和操作,但是在企业中,持久化到底是怎么去用得呢? 企业级的数据备份和各种灾难下的数据恢复,是怎么做得呢? 1.企业级的持久化 ...
- SpringBoot-集成通用mapper
SpringBoot-集成通用mapper SpringBoot-集成通用mapper 我们在SpringBoot中整合了MyBatis,但是大量重复的增删改查还是很头疼的问题,MyBatis也给 ...
- NO14 快照-克隆-必须掌握的Linux目录结构
壹 VMware克隆,快照讲解及相应问题讲解: ·快照:比喻:假设把人生作一个快照.1岁10岁20岁6无限还原到前一个设置的节点. ·克隆学习一般用链接克隆,不另外占用磁盘,但是依赖本体虚拟机.完整 ...