题目链接: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. 关于tomcat不同版本的maxPostSize

    tomcat7.0.63之前: maxPostSize The maximum size in bytes of the POST which will be handled by the conta ...

  2. JDK自带jvisualvm监控工具

    定位 工具位于jdk\bin目录下(双击运行): 可以本地或者远程调试,本地调试会自动加载,远程调试需要配置.下面以Tomcat为例. 概述 监视 线程 抽样器 Java 堆 百度经验参考:https ...

  3. 11g新特性 -- Virtual Private Catalogs

    在oracle 11g之前版本中,如果用户只是需要访问recovery catalog 中的某个数据库,但是我们却只能将整个recovery catalog授权给他,无法做到严格限制. 现在,virt ...

  4. openwrt 水星mw4530r-v1 搞搞搞

    感觉周围最实用的搞硬件非路由器莫属,可惜配置都不咋的高,选择水星这款就是看中它的性价比和openwrt的支持,真乃刷机神器啊,还可以挂载usb就更绝了,价格没得说. 另外128mb的rom对大部分功能 ...

  5. 2.4 Apache Axis2 快速学习手册之XMLBeans 构建Web Service

    4. 使用XMLBeans生成服务(通过xml bean 命令将wsdl 文件生成java 代码) 要使用XMLBeans生成服务,请执行以下步骤. 通过在Axis2_HOME / samples / ...

  6. Atitit 列出wifi热点以及连接

    Atitit 列出wifi热点以及连接 配置命令 >netsh wlan  /?1 显示已经有的配置netsh wlan show profiles1 C:\Users\Administrato ...

  7. linux每日命令(38):iostat命令

    Linux系统中的 iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视.它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况.同 ...

  8. JAVA(六)数据库/网络编程/新IO

    成鹏致远 | lcw.cnblog.com |2014-02-05 数据库 1.JDBC概述 JDBC(Java Database Connectivity,Java数据库连接)提供了一种与平台无关的 ...

  9. Virtualbox的centos7 nat和桥接网络配置

    在实际配置虚拟机的过程中,网络配置时候一个很繁琐的过程,经常一个点没注意到,就访问不了了.在此,做一个简单的教程以供后续使用时可以参考! 方法一: 使用NAT网络 1. 选择网卡 安装centos7的 ...

  10. 图片相似原理--Java实现

    前阵子在阮一峰的博客上看到了这篇<相似图片搜索原理>博客,就有一种冲动要将这些原理实现出来了. Google "相似图片搜索":你可以用一张图片,搜索互联网上所有与它相 ...