HDU 3183 贪心

来源:互联网 发布:筑业家装软件 编辑:程序博客网 时间:2024/06/06 02:15

题意

给一堆数字,从中删去M个数字并且去掉前导零以后,要求形成的数字最小,问形成的最小数字是多少。

题解

其实是很水的贪心题?好像可以用RMQ进一步优化,不过使用普通的贪心算法就可以达到一个不错的时间。贪心方法很简单,持续选择x[i]>x[i+1]的就可以了。这个是可以证明的,如果删掉i前面的任何一个数字,数字的总位数只会减少一位(其实也可以相当于后面的数字进了一位),这样形成的数字一定不如删掉i更划算。如果删掉i后面的任何一个数字,由于i占用着比较靠前的位置,所以一定不如删掉i,使得比i小的数字占据这个位置更划算。综上所述,删除i是最优选择。

代码

#include <iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<string>#include<set>#include<map>#include<bitset>#include<stack>#include<string>#define UP(i,l,h) for(int i=l;i<h;i++)#define DOWN(i,h,l) for(int i=h-1;i>=l;i--)#define W(a) while(a)#define MEM(a,b) memset(a,b,sizeof(a))#define LL long long#define INF 0x3f3f3f3f#define MAXN 800010#define MOD 1000000007#define EPS 1e-3using namespace std;char s[1010];int main() {    int m;    W(~scanf("%s%d",s,&m)) {        int n=strlen(s);        W(m) {            int tag=-1;            UP(i,0,n-1) {                if(s[i]>s[i+1]) {                    tag=i;                    break;                }            }            if(tag==-1) {                break;            }            UP(i,tag,n-1) {                s[i]=s[i+1];            }            m--;            n--;        }        bool first=true;        UP(i,0,n-m) {            if(first&&s[i]=='0')                continue;            first=false;            printf("%c",s[i]);        }        if(first) {            puts("0");        } else {            puts("");        }    }}