题目链接: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. php static 变量的例子

    class test { public static function a(){} public function b(){} } $obj = new test; 调用 代码 test::a(); ...

  2. 地图组件上的自定义区域叠加层显示 ArcGis + GeoJson

    最近参与了一个IOT环境项目,需要对某个城市的某几个区域做环境监控与治理,其中就用到了地图叠加层的功能,粗看很复杂,其实很简单,先来看一下效果,然后再来讲一下如何实现的: 中间的黄色轮廓线包括的几块区 ...

  3. 8个超实用的jQuery插件应用

    自jQuery诞生以来,jQuery社区都在不断地.自发地为jQuery创建许许多多功能不一的插件应用,很多jQuery插件非常实用,对我们的前端开发帮助相当大,不仅可以更完美的完成指定功能,而且节省 ...

  4. linux(mac) 编译安装MySQL

    Reference: https://blog.csdn.net/Tzhennan/article/details/80565235 官方下载地址:  https://dev.mysql.com/do ...

  5. ambari安装 QA

    1.在安装时 出现Public key for ambari-server-2.4.2.0-136.x86_64.rpm is not installed 安装ambari报错 在安装HST服务时也报 ...

  6. mysql 修改表的每个列的字符类型

    #!/bin/shfor i in $(mysql -uroot -p112358s uarticles_2019 -e "show tables;"|egrep -v Table ...

  7. Java知多少(59)创建多线程

    到目前为止,我们仅用到两个线程:主线程和一个子线程.然而,你的程序可以创建所需的更多线程.例如,下面的程序创建了三个子线程: // Create multiple threads. class New ...

  8. (实用)CentOS 6.3更新内置Python2.6

    在安装Kilo版的OpenStack时,我们发现社区已经将Python升到2.7,而CentOS 6.3上仍然在使用2.6版的Python.本文记录将CentOS 6.3内置的Python2.6更新为 ...

  9. win7下安装Office2010老是出现提示安装MSXML6.10.1129.0,下载官方MSXML后提示安装成功却也安装不了

    在注册表中增加以下信息: [HKEY_CLASSES_ROOT\TypeLib\{F5078F18-C551-11D3-89B9-0000F81FE221}][HKEY_CLASSES_ROOT\Ty ...

  10. Win10系统中VirtualBox桥接时找不到网卡的问题

    1.主机中 点网络连接 ,点 本地网络,右键属性 2.安装 服务 磁盘安装 选择 VirtualBox 安装目录, 找到 目录文件 D:\Users\Oracle\VirtualBox\drivers ...