ACM学习:贪心学习

本周学习内容主要是贪心,因为要顾及考试,所以看的题目数量不是很多,20道左右。不过涉及的题型很广,所以收获也不少。

贪心其实更像一种思路就是求得局部子问题求最优解,然后各个子问题汇总最优解得到整体最优解因此,如何确定分阶段,确定每一阶段的方法才是贪心最困难的部分。而也正是在这上面,经常会混入像优先队列(STL)、二分、树、并查集、搜索等等知识一起考察。这也正是我所说的,贪心更像思想的原因。

贪心的常规方法就是排序然后寻找自己想要的条件数据,不过,它的排序花样很多,例如,左/右端点排序,双要素排序等。而且,贪心有一些典型的问题,包括:子序列问题,最优装载问题,01背包问题,区间调度问题,货币找零问题,字典序最小问题,分发饼干问题等。这里就简单的提几个经典问题进行分析。

一.区间调度问题

区间调度问题主要是在排序的问题上,注意点是结束时间与下一个开始时间的交接点,然后根据问题输出。有时,会遇见一些对端点以及区间包含关系的特殊问题,如:选课(端点互不相交),早起时间安排(区间覆盖)等等,遇见变种的题目时,其核心思想还是排序与选择,只要根据题目要求,对端点的设置进行相应的限制(如不相等,或者更新最大值)就可以解决。

虽然这道题很典型且延展性很强,但我看的博客里类似的题型并不多,所以就不举例了。


二.子序列问题

子序列问题其实并不止子序列,它还包括了最长/短序列的构造问题,其问题的核心就是在对原序列的处理上,是字符串要去重?还是数组要计算和(公约数等等),这都可以看成对原序列进行不同处理而得到结果的情况,我个人就把他们放在一起组成一类问题了。

处理这类问题,其实就是经典的贪心思路,根据贪心的排序进行操作,操作或计数,或累加,或递归,极具变化,但其实不难理解。

例题:uva11039 设计建筑物

题目大意:对于一组数,选出绝对值递增且正负交替的最长序列长度。

题目分析:如我所说,经典贪心思路,先对数组绝对值排序,然后将相邻的同号数字视为一个子序列,统计完后直接输出序列个数。

代码:

#include<bits/stdc++.h>
using namespace std;
const int MAX=0X7fffff;
int a[MAX];
bool cmp(int a,int b)
{
    return abs(a)<abs(b);
}
int main()
{
    int t;
    cin >> t;
    for(int i=0;i<t;i++)
    {
        int n,dian,ans=1;
        cin >> n;
        memset(a,0,sizeof(a));
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        sort(a+1,a+n+1,cmp);
        if(a[1]<0)
        dian=-1;
        else
        dian=1;
        for(int i=2;i<=n;i++)
        {
            if(a[i]*dian<0)
            {
                ans++;
                dian = -dian;;
            }
        }
        cout << ans << endl;
    }
}

这就是一道很基础的贪心题,简洁而明了。

三.本周总结

本周遇见的题型其实并不少,虽然不算完全的符合我所列的经典题型。但都能看出他们相似的地方,比如ICPC World Finals A Azulejos 这道题,就是在子序列问题的基础上增加了一个不能大于后排高度的要求,实际上还是对序列的处理。还有LeetCode 870 Advantage Shuffle这道题,也是处理复杂的基础贪心题,只要建立两个数组,排序后按对应的方法交换就可以解答。如果对操作改变一点,像LeetCode 1775 Equal Sum Arrays With Minimum Number of Operations这个,就有独特的处理方法:即先确定有无解,(无解即数组1可能的最小值大于数组2可能的最大值),再挑选更简洁的方法(即大变小或小变大),对差值大的数进行更改,就能得到最小的更改次数了。而有的题,像codeforces 672C Recycling Bottles,其实质是对结点成图,求边权问题的贪心处理,这就是典型的贪心应用于别的知识点。

就像上面简述的几道题,我本周因为时间原因,对于大部分题目都是理清思路,搞清原理即过。A出代码的并不多,不过可以很清楚的看到,贪心是一个富有极强扩展性的解题方案,但我们更要考虑贪心的使用范围,不能一味强求最优解,因为贪心的原则是各个子问题无法产生回路干涉,如果两个子问题不断反复干涉,贪心的方法就只能放弃。

所以,本周虽然看了很多贪心的题,但对于贪心真正的使用我觉得只是凤毛麟角,更多的方法我应该在今后的学习中去努力尝试了。这周能给的代码不多,更多就是思路与感悟。那么下周继续努力吧。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值