C++ 算法学习——1.6 贪心算法

贪心算法依然是分析局部,不同于分治所研究的小问题,这些局部问题与整体问题并不是同结构的。如果局部最优解能带来整体最优解,那贪心算法就是可用于解决问题的。

使用步骤:

1.分析局部问题。

2.看是否局部最优解能带来整体最优解。

3.如果是,则使用贪心算法。

P1. 以洛谷P1080国王游戏为例(贪心和排序思路,未AC)

分析局部问题。可以考察两个相邻的大臣情况。分别设为l1,r1,l2,r2代表相应左右手的数。设前面若干人乘积为a。

则大臣1在大臣2前面情形时,两者最大值为:

max(\frac{a}{r1},\frac{a*l1}{r2})

若大臣2在大臣1前面,两者最大值为:

max(\frac{a}{r2},\frac{a*l2}{r1})

通过很简单的数学推导可以知道,当第二种情形最大值大于第一种情形最大值时,会得到:

l1r1<l2r2

意味着,如果按照l*r作为标准,大臣呈非减序列排列,就可以出现最大值最小的情况。

否则,一定存在相邻的两个大臣l1,r1,l2,r2,其中l1r1<l2r2,而大臣2在大臣1前面,则必然可以有大臣1在大臣2前面时最大值更小。也就是全局并非最优情况

于是这样的局部最优解推出全局最优解的情况,可以采用贪心算法。

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<string>
using namespace std;

struct minister
{
    int left;
    int right;
};

bool comparebymulti(minister &a,minister &b)
{
    return a.left*a.right<b.left*b.right?1:0;
}

void showcurqueue(vector<minister> a)
{
    for(int i=0;i<a.size();i++)
    printf("%d %d\n",a[i].left,a[i].right);
}



int main()
{
    int n;int kingleft,kingright;
    cin>>n>>kingleft>>kingright;

    vector<minister>ministers;
    for(int i=0;i<n;i++)
    {
        int leftp,rightp;minister p;
        cin>>leftp>>rightp;
        p.left=leftp;p.right=rightp;
        ministers.push_back(p);
    }
    sort(ministers.begin(),ministers.end(),comparebymulti);
    showcurqueue(ministers);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值