题目链接: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. 判断js数组包是否包含某个元素

    要判断数组中是否包含某个元素,从原理来来说,就是遍历整个数组,然后判断是否相等,我们来造个轮子,名字就山寨PHP的数组函数in_array() Array.prototype.in_array = f ...

  2. asp.net 逻辑操作符与(&&),或(||),非(!)

    逻辑操作符与(&&),或(||),非(!)能根据参数的关系返回布尔值 public class bool{ public static void main(string [] args ...

  3. [k8s]zookeeper集群在k8s的搭建(statefulset模式)-pod的调度

    之前一直docker-compose跑zk集群,现在把它挪到k8s集群里. docker-compose跑zk集群 zk集群in k8s部署 参考: https://github.com/kubern ...

  4. opencv 无法使用 dll 动态链接库 UnsatisfiedLinkError java.library.path Can't find dependent libraries

    System.loadLibrary(Core.NATIVE_LIBRARY_NAME) 使用如上方法加载本地 dll文件. 一般会出现两种错误: 1. UnsatisfiedLinkError ja ...

  5. @Transactional(rollbackFor = Exception.class)

    @Transactional(rollbackFor = Exception.class)这个注解只有在出异常时才会回滚,需要回滚时没有异常也要人为制造异常(自定义异常)所以,如果使用了异常捕获,很有 ...

  6. 解决Django-1.8.2应用部署到Apache后无法显示admin应用的CSS

    在将Django-1.8.2应用部署到Apache后,无法显示admin应用的静态内容,而在“manage.py runserver”命令下可以正常显示,主要是Apache没有找到Django静态内容 ...

  7. 提升linux下TCP服务器并发连接数(limit)

    https://cloud.tencent.com/developer/article/1069900 1.修改用户进程可打开文件数限制   在Linux平台上,无论编写客户端程序还是服务端程序,在进 ...

  8. 针对phpStudy网站服务器的入侵

    今天客户服务器上出现报警,查找了下原因,发现根目录下有wk.php E:\phpStudy\MySQL\bin\mysqld.exe, Version: (MySQL Community Server ...

  9. 多密钥ssh-key生成与管理

    由于 git 大文件用 http 方式难以传输,必须使用 ssh-key,而 ssh-key 又生成了好多个.最近在各种折腾 ssh,公钥私钥上花费了很多时间,现将一些问题总结如下.系统为 Mac/L ...

  10. 设计模式-行为型模式,python访问者模式

    访问者模式 在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法.通过这种方式,元素的执行算法可以随着访问者改变而改变.这种类型的设计模式属于行为型模式. ...