A Magic Lamp HDU - 3183 RMQ/贪心
题意就是数字串删m个字符让剩下的最小,剩下可含前导0
贪心是删掉第一个s[i]满足s[i]>s[i+1]
用rmq的话可以这样想,剩下数字串的最高位一定是s[1]~s[m+1]中的最小,设为s[x]
次高位就是s[x+1]~s[m+2]中的最小……递推一下就好
//#include<bits/stdc++.h> #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<set> #include<map> #include<vector> #include<iomanip> using namespace std; #define ll long long #define ld long double #define pb push_back #define FOR(a) for(int i=1;i<=a;i++) //const int inf=0x3f3f3f3f; #define inf 0x3f3f3f3f const long long Linf=9e18; const int maxn=1e5+90; char s[maxn]; int n,m; char num[maxn]; int _min(int i,int j){ return s[i]<=s[j]?i:j; } int MIN[maxn][20]; void ST(){ for(int i=1;i<=n;i++)MIN[i][0]=i; int k=log( (double)(n+1) )/log(2.0); for(int j=1;j<=k;j++) for(int i=1;i+(1<<j)-1<=n;i++) MIN[i][j]=_min(MIN[i][j-1],MIN[i+(1<<(j-1))][j-1]); } int rmq_min(int l,int r){ int k=log((double)(r-l+1))/log(2.0); return _min(MIN[l][k],MIN[r-(1<<k)+1][k]); } int main(){ while(~scanf("%s%d",s+1,&m)){ int len=strlen(s+1); n=len;m=len-m; //选m个数 ST(); int i=1,j=1; while(m--){ i=rmq_min(i,len-m); num[j++]=s[i++]; } for(i=1;i<j;i++){ //忽略前导0 if(num[i]!='0')break; } if(i==j){ puts("0");continue; //全0串 } while(i<j){ printf("%c",num[i]); i++; } puts(""); } }