hud 3183

题意:给出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("
");
    }
}
原文地址:https://www.cnblogs.com/linhaitai/p/9790856.html