HDU 3183 A Magic Lamp RMQ
2015-11-26 22:37
337 查看
题意:
给一串不含前导零的\(n\)个数字,要删去\(m(m \leq n)\)个数字,要使剩下的数字最小。分析:
删去\(m\)个数字就相当于选\(n-m\)个数字,因为最终选出来的数字的长度是一定的,所以第一个数字越小越好。第一个数字只能在区间\([1,m+1]\)中选,否则后面的就不够选了。
假设我们选在了位置\(p\),那么第二个数字就在区间\([p+1, m+2]\)中选,以此类推。
因此RMQ中我们要查询的是最小值的最左下标。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1000 + 10; char s[maxn], ans[maxn]; int n, m; int d[maxn][11]; int Min(int i, int j) { return s[i] <= s[j] ? i : j; } void init() { for(int i = 0; i < n; i++) d[i][0] = i; for(int j = 1; (1 << j) <= n; j++) { for(int i = 0; i + (1<<j) - 1 < n; i++) { d[i][j] = Min(d[i][j-1], d[i + (1<<(j-1))][j-1]); } } } int query(int L, int R) { int k = 0; while((1 << (k+1)) <= R - L + 1) k++; return Min(d[L][k], d[R-(1<<k)+1][k]); } int main() { while(scanf("%s", s) == 1) { n = strlen(s); scanf("%d", &m); init(); int choose = -1; for(int i = 0; i < n - m; i++) { choose = query(choose + 1, m + i); ans[i] = s[choose]; } ans[n - m] = 0; int st; for(st = 0; st < n - m; st++) if(ans[st] > '0') break; if(st >= n - m) printf("0\n"); else printf("%s\n", ans + st); } return 0; }
相关文章推荐
- 结构体定义 typedef struct 用法详解和用法小结 http://blog.sina.com.cn/s/blog_4fdabc820100fsxu.html
- androidStudio 自定义快捷代码的快捷方式
- opencv 学习记录
- Mac终端编写c语言程序方法
- 第一章 JavaWeb应用开发概述
- 输出100~200之间的素数
- linux注意事项
- Delphi编写的Android程序获取Root权限实现(2015.4.15更新,支持Android 4.4)
- Java解析XML
- 面向对象(上)
- jQuery自动触发事件trigger使用
- 二维子数组之和的最大值
- GCC知识整理
- jQuery自动触发事件trigger使用
- jQuery自动触发事件trigger使用
- 黑马程序员——Java笔记——正则表达式笔记
- Maven管理的jar包不能发布到/WEB-INF/lib中
- LintCode: Binary Tree Preorder Traversal
- spring源码(1)之初始化
- ios 设计模式备忘录(1)