UVALive 6440 Emergency Handling 【思维好题啊!!! + 优先队列处理】

传送门
// 题意: 给定n个操作, 如果是f表示有一个病人来就诊, a代表医院可以接受一个病人, 选择的规则为首先选严重程度最严重的, 如果相同就想等级高的, 在相同就可以随意选了. 病人的严重程度定义为 s = s0 + r(t - t0);
s0为基础严重度 , t0为送到医院来的时间, r 为改为病人的等级. A t. 表示医院在t时间要接受一位病人.

// 思路: 如果我们每次都是要把每个病人的严重度都相应于病人算出来, 那么每次这个答案都在变, 所以是个n方的复杂度, 必然不行, 所以我们需要对所给算法进行转换 s = s0 + rt - rt0, 所以我们可以看出我们是知道每个病人的s0 - rt0的, 而rt是根据医院的时间定的, 所以我们对此下手, 对于每个病人算出s0 - rt0 的值推到相应的等级优先队列中(最大值优先), 然后对于每次医院的t, 我们只需要从大到小的遍历每一个等级的最大值即可, 然后算一遍s, 更新一下答案就行啦, 最后删除我们选的那个病人即可. 复杂度为O(n/2*100).

// 所以像这种算式的, 我们应该进行一定的转换, 将一定可以确定的因素提出来进行分析就有眉目啦~
AC Code

void solve()
{
    int n; cin >> n ;
    priority_queue<int>q[105];
    for (int i = 1 ; i <= n ; i ++) {
        string s ;
        cin >> s;
        if (s[0] == 'P') {
            int t0, s0, r;
            cin >> t0 >> s0 >> r;
            q[r].push(s0 - r*t0);
        }
        else {
            int tt; cin >> tt;
            int ans = 0, id ;
            for (int i = 100 ; i >= 0 ; i --) {
                if(!q[i].empty()) {
                    int tmp = q[i].top() + i*tt;
                    if (tmp > ans ) {
                        ans = tmp;
                        id = i;
                    }
                }
            }
            q[id].pop();
            cout << ans << ' ' << id << endl;
        }
    }
}

你可能感兴趣的:(想法思维题)