P4053 [JSOI2007]建筑抢修

10 篇文章 0 订阅
1 篇文章 0 订阅

其實對於這一題可以使用貪心,而且很好證明正確性。

假設維修所需時間是Si,限時是Ti。

首先,我們對T進行排序,然後這個時候序列就有下面的特性了。

\\S_1,\;\;\;S_2,\;\;\;\;S_3........,S_n\\ T_1 \leq T_2\leq T_3.....\leq T_n

假如T3的時候可以維修3個,也就是說S_1 + S_2 +S_3 \leq T_3 ,那好如果S4進來了,

但是S1+S2+S3+S4卻大於T4,那麼我們是不是直接丟棄掉T4呢?其實不行,因為如果S4比起前面的如果小一點,那麼當然要把S4進行兌換,把耗時高一點的去掉。

這裡就會出現一個問題,你這樣換能保證正確性嗎?絕對能。 

我們知道 \\T_1\leq T_2 \leq T_3\leq T_4\\ 並且如果T3前能完成3個就說明  S_1 + S_2+S_3 \leq T_3\leq T_4

那麼就繼續照著上面說的兌換做一做數學推導。

Let \;S_{total}=S_1 + S_2+S_3,\;S_{max} = max(S_1,S_2,S_3)

S_{total} > S_{total} -S_{max}+S_4

\\\because S_{total} \leq T_3\leq T_4\\ \because S_{total}-S_{max}+S_4 < S_{total}\\ \therefore S_{total}-S_{max}+S_4 < T_3\leq T_4\\ \therefore S_{total}-S_{max}+S_4 < T_4

從這裡我們可以知道從時間消耗小了,但是能維修的房子數量卻沒有少。

#include <iostream>
#include <queue>
#include <algorithm>
#define MAXN 200200
using namespace std;
int n, T = 0, ans = 0;
struct node{
    int s, t;
}a[MAXN];
priority_queue<int> q;
bool cmp(node x, node y){
    return x.t < y.t;
}
int main(){
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> a[i].s >> a[i].t;
    }
    sort(a + 1, a + n + 1, cmp);
    for(int i = 1; i <= n; i++){
        if(T + a[i].s > a[i].t){
            if(a[i].s < q.top()){
                T -= q.top();
                q.pop();
                q.push(a[i].s);
                T += a[i].s;
            }
        }
        else{
            q.push(a[i].s);
            ans++;
            T += a[i].s;
        }
    }
    cout << ans;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值