题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3183

Problem Description
Kiki likes traveling. One day she finds a magic lamp, unfortunately the genie in the lamp is not so kind. Kiki must answer a question, and then the genie will realize one of her dreams.
The question is: give you an integer, you are allowed to delete exactly m digits. The left digits will form a new integer. You should make it minimum.
You are not allowed to change the order of the digits. Now can you help Kiki to realize her dream?

Input
There are several test cases.
Each test case will contain an integer you are given (which may at most contains 1000 digits.) and the integer m (if the integer contains n digits, m will not bigger then n). The given integer will not contain leading zero.

Output
For each case, output the minimum result you can get in one line.
If the result contains leading zero, ignore it.

Sample Input
178543 4
1000001 1
100001 2
12345 2
54321 2

Sample Output
13
1
0
123
321

题意:

给你一个 $n$ 位的数字,你要删除其中的 $m$ 位,使得剩下来的每一位组成一个新数字是最小的。

题解:

换句话说,就是要在 $n$ 位中选择 $k=n-m$ 位数字组成新数字,使其最小。

显然,新数字的最高位必须在 $[1,n-k+1]$ 内,否则后面的数字将不够用。因此我们可以按照贪心的策略在 $[1,n-k+1]$ 内寻找最小的数字作为最高位。

然后,就转变为一个子问题:去掉选定的最高位,以及其前面的所有数字,剩下来的一串数字里,寻找 $k-1$ 位数字组成最小新数字。

一般来说,线段树是区间查询最大值的一种非常优秀的解决方法。不过本题没有修改操作,用线段树比较浪费。本题适合使用解决RMQ问题的著名的ST算法。

ST算法是基于倍增思想的。对于一个给定的序列 $a[1 \sim n]$,它能够在 $O(n \log n)$ 的预处理后,以 $O(1)$ 的时间复杂度在线地给出任意区间的最值。

首先我们知道,对于序列 $a[1 \sim n]$,它的子区间数目是 $O(n^2)$ 的。根据倍增思想,我们在这 $O(n^2)$ 的状态空间内选择一些 $2$ 的整数次幂的位置作为关键位置。

假设 $f(i,j)$ 代表了区间 $[i,i+2^j-1]$ 的最大值,即以 $a[i]$ 为起始的 $2^j$ 个数的最大值。显然递推边界为:对于任意的 $i \in [1,n]$,有$f(i,0) = a[i]$。

接下来,在递推求 $f(i,j)$ 时,区间的长度是成倍增长的,即 $f(i,j) = \max[f(i,j-1),f(i+2^{j-1},j-1)]$。从这个递推式不难看出,只要我们从小到大枚举 $j$,且对于固定的 $j$ 枚举 $i$ 即可。

而当我们要求 $[l,r]$ 的最大值时,我们可以求得 $k = \log(r-l+1)$,显然从 $l$ 往后的 $2^k$ 个数和从$r$ 往前的 $2^k$ 个数能够完全覆盖 $[l,r]$,因此只需要返回 $f(l,k)$ 和 $f(r-2^k+1,k)$ 中的较大值即可。

以下为求解RMQ问题的ST算法模板:

namespace ST
{
int n;
int f[maxn][(int)log2(maxn)+];
void init(int _n,int* a)
{
n=_n;
for(int i=;i<=n;i++) f[i][]=a[i];
for(int j=;(<<j)<=n;j++)
for(int i=;i<=n-(<<j)+;i++)
f[i][j]=max(f[i][j-],f[i+(<<(j-))][j-]);
}
int query(int l,int r)
{
int k=log2(r-l+);
return max(f[l][k],f[r-(<<k)+][k]);
}
}

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int maxn=; int n,m,k;
char num[maxn];
queue<int> q; namespace ST
{
int n;
pii f[maxn][(int)log2(maxn)+]; //first存储最小值,second存储最小值位置
pii min(const pii& a,const pii& b)
{
if(a.first==b.first)
return a.second<b.second?a:b;
else
return a.first<b.first?a:b;
}
void init(int _n,char* a)
{
n=_n;
for(int i=;i<=n;i++) f[i][]=make_pair(a[i]-'',i);
for(int j=;(<<j)<=n;j++)
for(int i=;i<=n-(<<j)+;i++)
f[i][j]=min(f[i][j-],f[i+(<<(j-))][j-]);
}
pii query(int l,int r)
{
int k=log2(r-l+);
return min(f[l][k],f[r-(<<k)+][k]);
}
} void solve(queue<int>& q,int l,int r,int k)
{
if(k==) return;
pii x=ST::query(l,r-k+);
q.push(x.first);
solve(q,x.second+,r,k-);
}
int main()
{
while(scanf("%s%d",num+,&m)!=EOF)
{
n=strlen(num+), k=n-m;
ST::init(n,num);
solve(q,,n,k);
while(!q.empty())
{
if(q.front()==) q.pop();
else break;
}
if(q.empty()) q.push();
while(!q.empty())
{
printf("%d",q.front());
q.pop();
}
printf("\n");
}
}

HDU 3183 - A Magic Lamp - [RMQ][ST算法]的更多相关文章

  1. hdu 3183 A Magic Lamp RMQ ST 坐标最小值

    hdu 3183 A Magic Lamp RMQ ST 坐标最小值 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3183 题目大意: 从给定的串中挑 ...

  2. hdu 3183 A Magic Lamp(RMQ)

    题目链接:hdu 3183 A Magic Lamp 题目大意:给定一个字符串,然后最多删除K个.使得剩下的组成的数值最小. 解题思路:问题等价与取N-M个数.每次取的时候保证后面能取的个数足够,而且 ...

  3. HDU 3183 A Magic Lamp(RMQ问题, ST算法)

    原题目 A Magic Lamp Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. hdu 3183 A Magic Lamp rmq或者暴力

    A Magic Lamp Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Pro ...

  5. hdu 3183 A Magic Lamp(RMQ)

    A Magic Lamp                                                                               Time Limi ...

  6. HDU 3183 A Magic Lamp(二维RMQ)

    第一种做法是贪心做法,只要前面的数比后面的大就把他删掉,这种做法是正确的,也比较好理解,这里就不说了,我比较想说一下ST算法,RMQ的应用 主要是返回数组的下标,RMQ要改成<=(这里是个坑点, ...

  7. hdu 3183 A Magic Lamp 【RMQ】

    <题目链接> <转载于 >>>  > 题目大意: 给出一个长度不超过1000位的数,求删去m位数字以后形成的最小的数字是多少. 解题分析: 分析:我们可以把题 ...

  8. hdu 3183 A Magic Lamp(给一个n位的数,从中删去m个数字,使得剩下的数字组成的数最小(顺序不能变),然后输出)

    1.题目大意是,给你一个1000位的数,要你删掉m个为,求结果最小数. 思路:在n个位里面删除m个位.也就是找出n-m个位组成最小数 所以在区间 [0, m]里面找最小的数.相应的下标标号i 接着找区 ...

  9. hdu 3183 A Magic Lamp 贪心

    #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm& ...

随机推荐

  1. 【SqlServer】SqlServer的游标使用

    什么是游标 结果集,结果集就是select查询之后返回的所有行数据的集合. 游标则是处理结果集的一种机制吧,它可以定位到结果集中的某一行,多数据进行读写,也可以移动游标定位到你所需要的行中进行操作数据 ...

  2. ListView中的Item点击事件和子控件的冲突或者item点击没有反应的解决的方法

    fragment中加入了button和checkbox这些控件.此时这些子控件会将焦点获取到.所以经常当点击item时变化的是子控件.item本身的点击没有响应. 这时候就能够使用descendant ...

  3. curl 调用jenkins的api

    jenkins提供了rest api,通过调用接口,可以执行一些job的操作,如构建job ,新建job,启用禁用等操作骑车 其次curl是什么? cURL是一个利用URL语法在命令行下工作的文件传输 ...

  4. [k8s]一些技巧性的yaml和dockerfile-docker学习思路

    我会把一些dockerfile和yaml的技巧性东西不定期搜集到这里 docker学习思路 三部曲: 1,vm会搭建服务 2,docker会跑服务 3,k8s集群会调度该服务 存储 vm1 vm2 共 ...

  5. android 性能优化-工具篇

    一.Traceview 使用TraceView主要有两种方式: 1.直接打开DDMS,选择一个进程,然后按上面的“Start Method Profiling”按钮,等红色小点变成黑色以后就表示Tra ...

  6. 【Unity】讯飞语音识别SDK

    1.进入讯飞官网,注册帐号,进入控制台,创建新应用UnityXunfeiDemo,平台选Android.在当前应用这点下载SDK,添加AI能力(添加新服务),选择语音听写,即可下载安卓SDK(下称讯飞 ...

  7. 什么是位、字节、字、KB、MB (转)

    回顾一下按位操作符和移位操作符的知识,顺便复习一下位相关的基础知识. 位:"位(bit)"是电子计算机中最小的数据单位.每一位的状态只能是0或1. 字节:8个二进制位构成1个&qu ...

  8. js 上一步 下一步 操作

    <a id="syb" href="#" style="display: block;" class="btn button ...

  9. opencv2/nonfree/nonfree.hpp:没有那个文件或目录

    致命错误: opencv2/nonfree/nonfree.hpp:没有那个文件或目录 fatal error: opencv2/nonfree/nonfree.hpp: No such file o ...

  10. Angular4学习笔记(十)- 组件间通信

    分类 父子组件通信 非父子组件通信 实现 父子 父子组件通信一般使用@Input和@Output即可实现,参考Angular4学习笔记(六)- Input和Output 通过Subject 代码如下: ...