zoukankan      html  css  js  c++  java
  • 洛谷P1233 [木棍加工]

    戳这里看原题


    主要思路:

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

    首先可以按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
    ", ans); //输出答案(实际上就是a.size())
    31     return 0;
    32 }
    View Code
  • 相关阅读:
    重构前的程序:通过rsync命令抓取日志文件
    标准输入、输出和错误和文件重定向
    错误处理的思考
    测试和恢复性的争论:面向对象vs.函数式编程
    哈佛经济学家关于工作效率的意外发现
    追求代码质量: 监视圈复杂度
    天猫程序猿高端算法找妹子
    代码度量工具——SourceMonitor的学习和使用
    我们能从java的HelloWorld学到什么?
    Java高新技术第二篇:反射技术
  • 原文地址:https://www.cnblogs.com/aha--CYJ/p/8395016.html
Copyright © 2011-2022 走看看