UVa 11491 - Erasing and Winning ( 优先队列模拟 )

题意

给出一个长度为n的数字串, 要求删去d个数字, 使得剩下的总数字最大 (1 ≤ d < n ≤ 10^5 )

思路

根据贪心策略, 越高位的数字越大越好.
但取高位数字时同时要保证剩余量能够满足一共选出n-d个数字
考虑到用优先队列
但同时要记录下刚才取出的数字所在位置, 每次把队列中位置在上次选出数字所在位置之前的元素弹出

AC代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <map>
#define mst(a) memset(a, 0, sizeof(a))

using namespace std;

const int maxn = 1e5+10;

struct Node
{
    int v, pos;
    bool operator < (const Node& node) const {   //定义优先队列的排序方式
        return v < node.v || (v == node.v && pos > node.pos);
    }
}p[maxn];

string s;
priority_queue<Node> que;
int a, b, c, mrk;  //mrk用于记录目前出队卡到第几位

void init(){
    while( que.size() ){ que.pop(); }
    mrk = 0;
    s = "";
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    while( cin >> a >> b && a )
    {
        init();
        string ss = "";
        b = a - b; //b定义改为剩余多少数字
        cin >> s;
        for( int i = 0; i < a; i++ ){
            p[i].v = s[i] - '0';
            p[i].pos = i;
            if( i <= a - b )  que.push(p[i]);
        }
        int mrk = -1;
        int i = a - b;
        //cout << "size:" << que.size() << endl;
        while( b ){
            while( que.top().pos < mrk )    que.pop();
            //cout << que.top().v << endl;
            char tmp = que.top().v + '0';
            ss += tmp;
            mrk = que.top().pos;
            que.pop();
            if( i < a )  que.push(p[++i]);
            b--;
        }
        cout << ss << endl;
    }
    return 0;
}

TLE代码 ( 一开始没考虑到时间复杂度的超时代码 )

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <map>
#define mst(a) memset(a, 0, sizeof(a))

using namespace std;

const int maxn = 1e5+10;
string s;
typedef priority_queue<int> Q;
int a, b, c, mrk;  //mrk用于记录目前出队卡到第几位

void init(){
    //if( que.size() ){ que.empty(); }
    mrk = 0;
    s = "";
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    while( cin >> a >> b && a )
    {
        init();
        string ss = "";
        b = a - b; //b定义改为剩余多少数字
        cin >> s;
        int len = s.size();
        while( b-- ){
            Q que;
            int tmp;
            map<int, int> mp;
            //cout << mrk << ' ' << len-b << endl;
            for( int i = mrk; i < len - b && i < len; i++ ){
                tmp = s[i] - '0';
                que.push(tmp);
                if( !mp.count(tmp) )  mp.insert( make_pair(tmp, i) );
            }
            char a = que.top() + '0';
            ss += a;
            mrk = mp[que.top()]+1;
        }
        cout << ss << endl;
    }
    return 0;
}
posted @ 2018-04-03 14:36  JinxiSui  阅读(153)  评论(0编辑  收藏  举报