洛谷P1230智力大沖浪 題解

題目描述

小偉報名參加中央電視臺的智力大沖浪節目。本次挑戰賽吸引了衆多參賽者,主持人爲了表彰你們的勇氣,先獎勵每一個參賽者m元。先不要過高興!由於這些錢還不必定都是你的?!接下來主持人宣佈了比賽規則:ios

首先,比賽時間分爲n個時段(\(n≤500\)),它又給出了不少小遊戲,每一個小遊戲都必須在規按期限ti前完成(\(1≤t_i≤n\))。若是一個遊戲沒能在規按期限前完成,則要從獎勵費\(m\)元中扣去一部分錢\(w_i\)\(w_i\)爲天然數,不一樣的遊戲扣去的錢是不同的。固然,每一個遊戲自己都很簡單,保證每一個參賽者都能在一個時段內完成,並且都必須從整時段開始。主持人只是想考考每一個參賽者如何安排組織本身作遊戲的順序。做爲參賽者,小偉很想贏得冠軍,固然更想贏取最多的錢!注意:比賽絕對不會讓參賽者賠錢!spa

輸入格式

輸入文件riddle.in,共\(4\)行。code

第1行爲\(m\),表示一開始獎勵給每位參賽者的錢;排序

第2行爲\(n\),表示有\(n\)個小遊戲;遊戲

第3行有\(n\)個數,分別表示遊戲\(1\)\(n\)的規定完成期限;ip

第4行有\(n\)個數,分別表示遊戲\(1\)\(n\)不能在規按期限前完成的扣款數。string

輸出格式

輸出文件riddle.out,僅1行。表示小偉能贏取最多的錢。it

輸入輸出樣例

輸入 #1

10000
7
4 2 4 3 1 4 6
70 60 50 40 30 20 10io

輸出 #1

9950class

解析

堆+貪心
咱們有一個總數,目的是減去一部分數而使得總數減去這一部分數後總數爲最大的。
首先將全部的價值取相反數加到一個變量裏,而後咱們就把求最小值轉換爲求最大值了。
根據時間期限按照從小到大進行排序,而後按照如下思路:

  1. 若是當前時間小於等於當前期限,那麼就說明該任務是能夠作的,把作完該任務的價值放入堆中;
  2. 反之大於當前期限,咱們就比較堆頂價值與當前價值的大小,若是堆頂價值小於當前價值,那就進行替換。
    將堆中的元素所有相加而後與總數相加就是答案。
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>
#include <iomanip>
#include <cstring>
#define re register
#define Max 550
struct IQ {
    int x, val;
    friend bool operator < (IQ a, IQ b) {
        return a.x < b.x;
    }
}t[Max];
int n, ans, m, T = 1;
std :: priority_queue<int, std :: vector<int>, std :: greater<int> > q;
int main() {
    scanf("%d%d",&m,&n);
    for(re int i = 1; i <= n; ++ i) scanf("%d",&t[i].x);
    for(re int i = 1; i <= n; ++ i) scanf("%d",&t[i].val), ans += -t[i].val;
    std :: sort(t+1,t+1+n);
    for(re int i = 1; i <= n; ++ i) {
        if(T <= t[i].x) T ++, q.push(t[i].val);
        else if(t[i].val > q.top()) q.pop(), q.push(t[i].val);
    }
    while(!q.empty()) ans += q.top(), q.pop(); 
    printf("%d",m+ans);
    return 0;
}
相關文章
相關標籤/搜索