2021-03-20

第二周学习总结——贪心算法

一、思想:利用局部的最优解以此来达到求全局最优解。
二、解题思路:
看到一个题时,基本不可能一眼看出此题要用贪心算法,所以就要先读懂题,不要受贪心思想的限制,先用基础的数学思路做出题,再寻找可以优化的地方或总结出规律,然后总体观察,考虑贪心算法思想,利用stl等方法优化题目。
三:本周学习的最大收获:我感觉就是模拟的思想。遇到题目不要着急,一步步的模拟总结出规律或可以优化的地方。
四:一些具体题目的题解报告
1、有m个人,每人得到n张牌,牌的号码是1到n*m的任意无重复的数,问我至少能赢几局。
自己的思路:只要是有大于我现在牌的牌,就会输,那么就从后向前找,只要这张牌我没有,比我所有牌都大的牌就多一张,如果我有这张牌并且比我所有牌大的牌的数量大于零本局就会输,想反如果我有这张牌并且比我所有牌大的牌的数量等于零本局就会赢。
具体代码如下

#include<iostream>
#include<algorithm>
#include<set>
#include<cmath>
using namespace std

int main()
{
    ios::sync_with_stdio(false);
    int n,m,p=1;
    while(cin>>n>>m)
    {
        if(m==0||n==0)
            break;
        int i,j,s=0,o,a[1001]= {0},f=0;//s用来记录赢的局数,f记录比我所有牌都大的数量,数组a用来记录每张牌我拥有的情况,初始把所有的a记录为0
        for(i=1; i<=m; i++)
        {
            cin>>o;
            a[o]=1;
        }//输入每张我拥有的牌的大小,并且用数组记录下来
        for(i=m*n; i>0; i--)
        {
            if(a[i]&&!f)
            {
                s++;
                continue;
            }//如果这张牌我有,并且f等于0,那么本局就会赢,continue必须要有
            if(a[i]&&f)
            {
                f--;
                continue;
            }//如果这张牌我有,并且f不等于0,那么本局就会输,然后这张牌用过了(不能在被使用),f需要减1
            f++;
            //以上的情况都不满足,即我没有这张牌,continue必须要有
        }
        cout << "Case "<<p<<": " <<s<< endl;
        p++;
    }
}

老师的讲解:把此题转化为最多输max次,则至少赢n-max次,用对方的最小牌依次和你的牌比较如果你的牌有比对方牌小的,则输的次数加1(代码就不在展示,课件上有)。
2、就是课件上的碰撞问题。(自我感觉收获最大的题)
题意:给出n个物体的质量,(假设两个物体的质量为m1,m2)相互碰撞成一个物体,质量为2sqrt(m1m2),只存在两个物体相撞,求最后最少质量。
思路:虽然知道这是贪心的题,但是也不知道具体怎么贪心,这就要先模拟总结。先假设三个物体质量a,b,c(a>b>c),碰撞后总质量为m。
a,b先碰:m=sqrt(sqrt(2ab)2c)
b,c先碰:m=sqrt(sqrt(2bc)2a)
a,c先碰:m=sqrt(sqrt(2ac)2b)
由此可知,先碰撞的开方的次数多,所以质量大的先碰撞最后总质量小。
最后,解决每次质量大的先碰撞问题,用优先队列自动把最大的放在前面,每次碰完在删除他,又把最大的放前面循环往复…
(至于代码也不必Ctrl+c,Ctrl+v的在搬过来了吧)
五、打代码的注意事项
1、解决性价比问题时,最好用乘法代替,用除法的话还要解决int和double之间的转化等问题。
2、区间调度问题,如果解决最参与的问题,最好按照结束时间升序排列。
六、感受:
感觉贪心算法的题目很难,每次都连题意都很难读懂,然后就会非常烦恼更加做不出,所以每次做题要心平气和,一步一步来,先读懂题,先用朴素的方法解决,再想办法优化,最终解决问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值