这道题吭哧了挺久的,主要是贪心算法设计的有问题。。
最开始的想法是:从第一个数开始在最大的范围内搜索最大值,作为第一位数字,之后从这个最大值的下一位开始,重复这个搜索,直到删除的数字达到上限。这样做重复了很多无用功,会TLE
最后改为:从前往后扫描,每次遇到 ai > aj (i<j) 的情况,则从i开始往前扫,删掉所有小于ai的。
另外还有一些细节需要小心,比如连续很多位相同的数字。
Run Time:0.033s
#define UVa "8-4.11491.cpp"
char fileIn[30] = UVa, fileOut[30] = UVa;
#include<cstring>
#include<cstdio>
#include<ctype.h>
#include<vector>
using namespace std;
//Global Variables. Reset upon Each Case!
const int maxn = 100000 + 10;
int del[maxn];
/
int main() {
int N, D;
while(scanf("%d%d", &N, &D) && (N || D) ) {
memset(del, 0, sizeof(del));
char a[maxn];
scanf("%s", a);
int cnt = 0;
int prev = -1;
while(cnt < D && cnt != prev) {
prev = cnt;
int last = a[0], lastpos = 0;
for(int i = 1; i < N; i ++) {
if(!del[i]) {
if(!del[lastpos] && a[i] > last && cnt < D) {
del[lastpos] = 1;
cnt ++;
for(int j = i - 1; j >= 0; j --) { //scan backward. delete all that smaller than a[i], until meet a[j] >= a[i].
if(!del[j] && a[j] < a[i] && cnt < D) {
del[j] = 1;
cnt ++;
}
if(!del[j] && a[j] >= a[i]) break;
}
}
last = a[i];
lastpos = i;
}
}
}
if(cnt == prev) { //can't delete anymore: the sequence is decreasing, select first N-D items only.
int p = N-1;
while(cnt < D) {
if(!del[p] && cnt < D) {
del[p] = 1;
cnt ++;
}
p--;
}
}
for(int i = 0; i < N; i ++) {
if(!del[i]) printf("%c", a[i]);
}
printf("\n");
}
return 0;
}