[JSOI2007]建筑抢修 [USACO09OPEN]Work Scheduling G ###K ###K ###K ###K //K

题目链接:https://www.luogu.com.cn/problem/P4053

题目链接:https://www.luogu.com.cn/problem/P2949

思路:考虑从截止时间短的来取  但这样取会发现如果有一段时间太长

可能会导致后面取的失去机会。那么就考虑如果前面的长 后面短的是否有机会替换掉他。

假设当前这个i 能够修好 那么就修 假设不能修好 和前面最长的一段比较,如果比他短 那么说明

可以不修前面那一段最长的 而修这一段 这样可以让后面的可选择的更多  因为是一直在维护一个最大值

那么用优先队列来维护    时间复杂度o(nlogn)

 

其实这是 贪心中的经典的后悔法 按照能选先选 后面的更优的代替前面的即可

一般做法是 排序 一个值 来确定顺序后 加优先队列来维护 后悔操作

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define pi pair<int,int>
 5 #define pb push_back
 6 #define fi first
 7 #define sc second
 8 #define ull unsigned long long
 9 const int maxn=2e5+10;
10 const int mod=1e9+7;
11 
12 
13 struct ac
14 {
15     int s,t;
16     bool operator<(ac a)
17     {
18         return t<a.t;
19     }
20 };
21 ac a[maxn];
22 
23 int main()
24 {
25     ios::sync_with_stdio(0);
26     cin.tie(0);
27     cout.tie(0);
28     int n;
29     cin>>n;
30     for(int i=1;i<=n;i++) cin>>a[i].s>>a[i].t;
31     sort(a+1,a+1+n);
32     priority_queue<int>q;
33     ll sum=0;
34     for(int i=1;i<=n;i++)
35     {
36         q.push(a[i].s);
37         sum+=a[i].s;
38         while(sum>a[i].t)
39         {
40             sum-=q.top();
41             q.pop();
42         }
43     }
44     cout<<q.size()<<'\n';
45 
46 }
View Code

 另外一道 也是后悔法

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define pb push_back
 5 const int maxn =2e5+10;
 6 const int mod=1e9+7;
 7 struct ac
 8 {
 9     int d,p;
10     bool operator<(ac a)
11     {
12         return d<a.d;
13     }
14 };
15 ac a[maxn];
16 
17 struct bc
18 {
19     int v;
20     bool operator<(bc a)const
21     {
22         return v>a.v;
23     }
24 };
25 
26 int main()
27 {
28     ios::sync_with_stdio(false);
29     cin.tie(0);
30     int n;
31     cin>>n;
32     for(int i=1;i<=n;i++)
33     {
34         cin>>a[i].d>>a[i].p;
35     }
36     sort(a+1,a+1+n);
37     priority_queue<bc>q;
38     ll ans=0;
39     int now=0;
40     for(int i=1;i<=n;i++)
41     {
42         if(now+1<=a[i].d)
43         {
44             ans+=a[i].p;
45             now++;
46             q.push({a[i].p});
47         }
48         else
49         {
50             if(q.top().v<=a[i].p)
51             {
52                 ans-=q.top().v;
53                 q.pop();
54                 ans+=a[i].p;
55                 q.push({a[i].p});
56             }
57         }
58     }
59     cout<<ans<<'\n';
60 
61 
62 }
View Code

 

posted @ 2020-06-06 11:15  canwinfor  阅读(107)  评论(0)    收藏  举报