题意:给出n个数字的字符串,要求你删除m个数字后,得到的数字最小。
分析:删除m个,就是选n-m个,而且,选的第一个数,肯定在(0—(n-m-1))中,第二个就在(第一个的下一位—(n-m-2)中。就这样,RMQ选出最小就可以了。
代码:
#include<stdio.h> #include<iostream> #include<math.h> #include<algorithm> #include<string.h> using namespace std; char str[1005]; int dp[1005][11];//存下标 int Min(int x,int y) { if(str[x]>str[y]) return y; else return x; } void RMQ_ST(int n) { for(int i=0;i<n;i++) dp[i][0]=i; for(int j=1;(1<<j)<=n;j++) for(int i=0;i+(1<<j)-1<n;i++) { dp[i][j]=Min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); } } int RMQ_Q(int L,int R) { int k=(int)(log(R-L+1.0)/log(2.0)); return Min(dp[L][k],dp[R+1-(1<<k)][k]); } int main() { int m; while(~scanf("%s%d",str,&m)) { int len=strlen(str); RMQ_ST(len); m=len-m;//选n-m个 int t=0; int top=0; int ant[1005]; memset(ant,-1,sizeof(ant)); while(m--)//依次选 { int k=RMQ_Q(top,len-m-1); ant[t]=str[k]; top=k+1; t++; } int f=0; while(ant[f]=='0')f++; if(f==t)printf("0"); while(f<t)//输出 { printf("%c",ant[f]); f++; } printf("\n"); } }