码迷,mamicode.com
首页 > 其他好文 > 详细

洛谷P1233 [木棍加工]

时间:2018-02-01 00:20:47      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:图片   view   lower   include   维护   friend   动手   分享图片   new   

戳这里看原题


 

主要思路:

这道题一眼看过去就可以贪心。。

首先可以按L排序。。

显然排序之后我们就可以抛开L不管了。。

然后就可以愉快的贪心了。。


细节:

这道题可以看成用 最少的合法序列(详见原题) 装下所有木棍。。

可以考虑用一种数据结构来记录序列最末端的木棍。。

可以考虑先按上述思路排序,

然后每次加木棍时加在第一个大于等于当前木棍宽度的木棍的序列末端,

然后顶替掉找到的这一位。

如果找不到这样的木棍就再开一个序列。。 (本题贪心的核心思想)

然而我懒得多动手,就用了STL的set来维护每个序列的末端木棍的宽度。。

set是C++中自带的红黑树(二叉平衡树),可以很方便地查找、插入和删除。

时间复杂度都是log级别。。

显然时间复杂度O(nlogn), 空间复杂度O(n)

剩下就是代码的事了。。(带注释):

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 5000;
 4 int n, ans;
 5 struct P {
 6     int a, b;
 7     friend bool operator < (P x, P y) { //set套结构体要重载<运算符
 8         return x.b < y.b;
 9     }
10 }s[N + 1];
11 bool cmp(P x, P y) { //将木棍按长度排序
12     if(x.a != y.a) return x.a > y.a;
13     return x.b > y.b;
14 }
15 set<P>a;
16 set<P>::iterator it; //定义一个set<P>的迭代器
17 int main() {
18     scanf("%d", &n);
19     for(int i = 1; i <= n; i++) 
20         scanf("%d%d", &s[i].a, &s[i].b);
21     sort(s + 1, s + 1 + n, cmp); //按照长度排序
22     for(int i = 1; i <= n; i++) {
23         if(a.empty()) a.insert(s[i]), ans++; //一定要这一步,不然没有元素时直接lower_bound会RE
24         else {
25             it = a.lower_bound(s[i]); //用lower_bound找到第一个大于等于当前木棍宽度的木棍
26             if(it == a.end()) a.insert(s[i]), ans++; //没有这样的木棍就再开一个序列
27             else a.erase(it), a.insert(s[i]); //否则就不用开,然后把这个木棍顶替掉之前这个序列的末尾木棍
28         }
29     }
30     printf("%d\n", ans); //输出答案(实际上就是a.size())
31     return 0;
32 }
View Code

 

洛谷P1233 [木棍加工]

标签:图片   view   lower   include   维护   friend   动手   分享图片   new   

原文地址:https://www.cnblogs.com/aha--CYJ/p/8395016.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!