摘要

题目链接 难度等级 完成状态 完成分数 最后编辑时间 需要注意
Sasha vs. Kate ★☆☆☆☆ 答案正确 100 2015-2-19 21:08:48 3

(AC 1212)

题意

给一个数,求去掉k位后的最大值。

题解

  • 设该数n位,由题意显然是要使得答案的最高位尽量大,即取原数第1位到n-(n-k)+2位(保证后面位数够)之间的最大值,而之后每一位都取上一位位置到n-(n-k)+i+1位的最大值即可。区间最值可以用线段树处理。
  • 另一种可行的弹性策略是:每次从最高位遇到非递减的字符则删除(如果整个序列都是递减的,则删除最后一个数),直到够为止。如,19192,遇到连续上升的19则删除一个1,贪心正确性待证明[1][2]

代码

296.cpp代码已折叠
展开折叠内容
显示/移除行号
  1. #include<cstdio>
  2. #include<string>
  3. #include<iostream>
  4. #include<algorithm>
  5. #define si(n) scanf("%d",&n)
  6. #define dsi(n) int n;si(n)
  7. using namespace std;
  8. string str;
  9. class ch
  10. {
  11. public:
  12. char p;
  13. int index;
  14. ch():p(0),index(0){};
  15. friend bool operator <(const ch&a,const ch&b){return a.p==b.p?a.index>b.index:a.p<b.p;}
  16. };
  17. template<size_t N>
  18. class SegmentTree
  19. {
  20. //模板:线段树//
  21. public:
  22. ch tree[N];
  23. #define cm int m=(l+r)>>1
  24. #define lp p<<1
  25. #define rp p<<1|1
  26. #define lc lp,l,m
  27. #define rc rp,m+1,r
  28. #define stdp int p,int l,int r
  29. ch build(stdp)
  30. {
  31. if(l==r)
  32. {
  33. tree[p].p=str[l-1];
  34. tree[p].index=l;
  35. return tree[p];
  36. }
  37. cm;
  38. return tree[p]=max(build(lc),build(rc));
  39. }
  40. ch query(int L,int R,stdp)
  41. {
  42. if(L<=l&&r<=R) return tree[p];
  43. ch ret;
  44. ret.p=0;
  45. cm;
  46. if(L<=m)ret=max(query(L,R,lc),ret);
  47. if(R>m)ret=max(query(L,R,rc),ret);
  48. return ret;
  49. }
  50. };
  51. SegmentTree<20000> st;
  52. int n;
  53.  
  54. int main()
  55. {
  56. cin>>str;
  57. int n=str.size();
  58. st.build(1,1,n);
  59. dsi(k);
  60. k=n-k;//fixed//
  61. string a;
  62. int lastIndex=0;
  63. for(int i=0;i<k;++i)
  64. {
  65. ch ret=st.query(lastIndex+1,n-k+i+1,1,1,n);
  66. cout<<ret.p;
  67. lastIndex=ret.index;
  68. }
  69. cout<<a;
  70. }
  71.  

参考资料和拓展阅读

  1. 跳转 http://blog.csdn.net/yzbyzz/article/details/9393889
  2. 跳转 http://www.cppblog.com/willing/archive/2010/05/07/114778.html

著作权声明[编辑]

关于[编辑]