题意:删去m个数,使剩下的数组成的数最小

题解 :贪心 , RMQ

RMQ解法,建st表找,用rmq找最小值的下标,注意点 ,因为最小值是区间最右最小值,所以应该改成 <= 而不是<

  1. minpos[i][j] = b[minpos[i][j - ]] <= b[minpos[i + ( << (j - ))][j - ]] ? minpos[i][j - ] : minpos[i + ( << (j - ))][j - ];

且rmq查询也要同步

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<string>
  4. #include<cmath>
  5. #include<cstring>
  6. using namespace std;
  7. #define MAXN 20000 +9
  8. #define MAXE 22
  9. int h[MAXN],minpos[MAXN][MAXE];
  10. int F_Min[MAXN][MAXE];
  11. int N,Q;
  12. int L,R;
  13. // void RMQ_ST(){
  14. // for(int i=1;i<=N;i++){
  15. // mmax[i][0]=h[i];
  16.  
  17. // }
  18. // int end_j=log(N+0.0)/log(2.0);
  19. // int end_i;
  20. // for(int j=1;j<=end_j;j++){
  21. // end_i=N+1-(1<<j);
  22. // for(int i=1;i<=end_i;i++){
  23. // //mmax[i][j]=max(mmax[i][j-1],mmax[i+(1<<(j-1))][j-1]);
  24. // mmin[i][j]=min(mmin[i][j-1],mmin[i+(1<<(j-1))][j-1]);
  25. // }
  26. // }
  27. // }
  28.  
  29. // int QueryMin(int L,int R){
  30.  
  31. // int k=log(R-L+1.0)/log(2.0);
  32. // return min(mmin[L][k],mmin[R-(1<<k)+1][k]);
  33. // }
  34.  
  35. void RMQ_pos_init(int n, int b[]){
  36. int i, j;
  37. for (i = ; i <= n; i++) {
  38. // maxpos[i][0] = i;
  39. minpos[i][] = i;
  40. }
  41. for (j = ; ( << j) <= n; j++)
  42. for (i = ; i + ( << j) - <= n; i++){
  43. minpos[i][j] = b[minpos[i][j - ]] <= b[minpos[i + ( << (j - ))][j - ]] ? minpos[i][j - ] : minpos[i + ( << (j - ))][j - ];
  44. //maxpos[i][j] = b[maxpos[i][j - 1]] > b[maxpos[i + (1 << (j - 1))][j - 1]] ? maxpos[i][j - 1] : maxpos[i + (1 << (j - 1))][j - 1];
  45. }
  46.  
  47. }
  48.  
  49. int RMQ_pos_min(int s, int v, int b[]){
  50. int k = (int)(log((v - s + )*1.0) / log(2.0));
  51. return b[minpos[s][k]] <= b[minpos[v - ( << k) + ][k]] ? minpos[s][k] : minpos[v - ( << k) + ][k];
  52. }
  53.  
  54. char str[+ ];
  55. int ans[ + ];
  56. int main(int argc, char const *argv[])
  57. {
  58. int n;
  59. while(~scanf("%s %d",&str,&n)){
  60. int len = strlen(str);
  61. int l = , r = n + ;
  62. int m = len - n ;
  63. int sum = ;
  64. for(int i = ; i < len; i ++){
  65. h[i + ] = str[i] - '';
  66. }
  67. // for(int i = 1;i )
  68. RMQ_pos_init(len,h);
  69. while(m--){
  70. int i = l ;
  71. int size = l ;
  72. // for(;i <= r;i++){
  73. // if((str[i] - '0') < (str[size] - '0')) size = i;
  74. // }
  75. //cout << l << " " << r << endl;
  76. size = RMQ_pos_min(l,r,h);
  77. //cout << size << endl;
  78. ans[sum++] = h[size];
  79. l = size + ;
  80. r++;
  81. }
  82. int i = ;
  83. while(ans[i] == && i < sum) i++;
  84. if(i == sum) printf("");
  85. else
  86. // for(auto au : ans){
  87. // printf("%d",ans );
  88. // }
  89. for(;i < sum; i++) printf("%d",ans[i]);
  90. printf("\n");
  91.  
  92. }
  93. return ;
  94. }

RMQ

贪心解法

删除m个数字,相当于在里面从左往右取n-m个数字;所得数最小,也就是每次取得数字尽量小。那么,取得的第一个数字一定在区间[0,m]内,为什么呢?因为除了第一个数之外还要取n-m-1个数字,所以区间右边界最大只能是m,每次在区间里找最小的那个数(尽量靠左);依次类推,假设第一个数字取得的下标是index1,那么,第二个数字一定是在[index1+1,m+1]内取得;依次类推下去,右边界每次加1。当选取到了n-m个数字之后,也就找到了答案了~

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<string>
  4. #include<cmath>
  5. #include<cstring>
  6. using namespace std;
  7. #define MAXN 200000 +9
  8. #define MAXE 22
  9. int h[MAXN],mmax[MAXN][MAXE];
  10. int N,Q;
  11. int L,R;
  12. void RMQ_ST(){
  13. for(int i=;i<=N;i++){
  14. mmax[i][]=h[i];
  15.  
  16. }
  17. int end_j=log(N+0.0)/log(2.0);
  18. int end_i;
  19. for(int j=;j<=end_j;j++){
  20. end_i=N+-(<<j);
  21. for(int i=;i<=end_i;i++){
  22. mmax[i][j]=max(mmax[i][j-],mmax[i+(<<(j-))][j-]);
  23. // mmin[i][j]=min(mmin[i][j-1],mmin[i+(1<<(j-1))][j-1]);
  24. }
  25. }
  26. }
  27. int QueryMax(int L,int R){
  28.  
  29. int k=log(R-L+1.0)/log(2.0);
  30. return max(mmax[L][k],mmax[R-(<<k)+][k]);
  31. }
  32.  
  33. char str[+ ];
  34. int ans[ + ];
  35. int main(int argc, char const *argv[])
  36. {
  37. int n;
  38. while(~scanf("%s %d",&str,&n)){
  39. int len = strlen(str);
  40. int l = , r = n;
  41. int m = len - n;
  42. int sum = ;
  43. while(m--){
  44. int i = l;
  45. int size = l;
  46. for(;i <= r;i++){
  47. if((str[i] - '') < (str[size] - '')) size = i;
  48. }
  49. ans[sum++] = str[size] - '';
  50. l = size + ;
  51. r++;
  52. }
  53. int i = ;
  54. while(ans[i] == && i < sum) i++;
  55. if(i == sum) printf("");
  56. else
  57. // for(auto au : ans){
  58. // printf("%d",ans );
  59. // }
  60. for(;i < sum; i++) printf("%d",ans[i]);
  61. printf("\n");
  62.  
  63. }
  64. return ;
  65. }

贪心

3183 RMQ / 贪心(坑成。。)的更多相关文章

  1. 【bzoj5073】[Lydsy1710月赛]小A的咒语 后缀数组+倍增RMQ+贪心+dp

    题目描述 给出 $A$ 串和 $B$ 串,从 $A$ 串中选出至多 $x$ 个互不重合的段,使得它们按照原顺序拼接后能够得到 $B$ 串.求是否可行.多组数据. $T\le 10$ ,$|A|,|B| ...

  2. hduacm 3183 rmq

    http://acm.hdu.edu.cn/showproblem.php?pid=3183 问题等价与取N-M个数,每次取的时候保证后面能取的个数足够,并且取的数最小  查询最小用rmq #incl ...

  3. HDU3183 RMQ/贪心

    A Magic Lamp Problem Description Kiki likes traveling. One day she finds a magic lamp, unfortunately ...

  4. hdu 3183 rmq+鸽巢原理

    题目大意: 给你一个数字字符串序列,给你要求删掉的数字个数m,删掉m个数使的剩下的数字字符串的之最小.并输出这个数字: 基本思路; 这题解法有很多,贪心,rmq都可以,这里选择rmq,因为很久没有写r ...

  5. hdu 3183(贪心)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3183 思路:比较前后两个相邻的字符,如果前面一个字符大于后面一个字符,就把它去掉. #include ...

  6. HDU 6034 Balala Power! (贪心+坑题)

    题意:给定一个 n 个字符串,然后问你怎么给 a-z赋值0-25,使得给定的字符串看成26进制得到的和最大,并且不能出现前导0. 析:一个很恶心的题目,细节有点多,首先是思路,给定个字符一个权值,然后 ...

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

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

  8. [APIO / CTSC2007]数据备份 --- 贪心

    [APIO / CTSC 2007]数据备份 题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份. 然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公 ...

  9. CTSC2015&APIO2015滚粗记

    CTSC 这次CTSC的考试,觉得还是考出了自己该有的水平.虽然自己最后还是没有得到金牌,但是我觉得自己尽力了,也没有什么太大的遗憾.比起省选,自己在应试的方面又有了很大的进步. Day1是我主要捞分 ...

随机推荐

  1. sql优化-派生表与inner-join

    首先来说明一下派生表? 外部的表查询的结果集是从子查询中生成的.如下形式: select ... from (select ....) dt 如上形式中括号中的查询的结果作为外面select语句的查询 ...

  2. sqlserver 2012 中的 sysobjects

    sysobjects 表  在数据库内创建的每个对象(约束.默认值.日志.规则.存储过程等)在表中占一行

  3. UITableView和MJReFresh结合使用问题记录

    1. 代码主动调用下拉刷新, [self.tableView.mj_header beginRefreshing]; 调用会走: [MJRefreshNormalHeader headerWithRe ...

  4. 简单说说JavaBean的使用

    一:JavaBean定义 JavaBean是一种可重复使用.跨平台的软件组件.JavaBean可分为两种:一种是有用户界面(UI,User Interface)的JavaBean,例如中的那些可视化图 ...

  5. 超大文件上传方案( Java )

    1.介绍enctype enctype 属性规定发送到服务器之前应该如何对表单数据进行编码. enctype作用是告知服务器请求正文的MIME类型(请求消息头content-type的作用一样) 1. ...

  6. [HTML]时钟

    <div class="clock" id="clock"> <!-- 原点 --> <div class="origi ...

  7. 使用eclipse导入新项目时中文出现乱码问题

    有时候在github上看到别人不错的项目想要拉下来学习学习的时候,总会出现这样的情况,实在蛋疼. 一般出现这种问题,会有三个地方需要改动: 在项目上右键选择 properties 将 text fil ...

  8. 启用和配置 FILESTREAM

    2017/08/23 在开始使用 FILESTREAM 之前,必须在 SQL Server 数据库引擎实例中启用 FILESTREAM. 本主题说明了如何使用 SQL Server 配置管理器来启用 ...

  9. scipy几乎实现numpy的所有函数

    NumPy和SciPy的关系?   numpy提供了数组对象,面向的任何使用者.scipy在numpy的基础上,面向科学家和工程师,提供了更为精准和广泛的函数.scipy几乎实现numpy的所有函数, ...

  10. slider组件

    slider组件,是一个强大的滑动选择器组件: 属性: min:类型 数字 滑动选择器的(范围)最小值 max:类型 数字 滑动选择器的(范围)最大值 step:类型 数字 步长(滑一次走的距离)  ...