贪心算法

动态规划方法:自底向上构造子问题的解,对每一个子树的根,求出下面每一个叶子的值,并且以其中的最优值作为自身的值,其它的值舍弃。

贪心算法 :是动态规划方法的一个特例,可以证明每一个子树的根的值不取决于下面叶子的值,而只取决于当前问题的状况。换句话说,不需要知道一个节点所有子树的情况,就可以求出这个节点的值。由于贪心算法的这个特性,它对解空间树的遍历不需要自底向上,而只需要自根开始,选择最优的路,一直走到底就可以了。(突然想起关于不同人吃葡萄的方式:贪心算法就相当于永远吃剩下的葡萄中最大的那颗)

实例1:有一个长为n的数组A,求满足0≤a≤b

class LongestDistance {
public:
    int getDis(vector<int> A, int n) {
        // write code here
        int minValue = A[0];
        int max = 0;
        for(int i = 0;i<n;++i){
            if(A[i]<minValue)//如果A[i]比minValue更小,则后面的值与A[i]的差值必定大于和minValue的差值
                minValue = A[i];
            if(A[i]-minValue>max) 
                max = A[i]-minValue;
        }
        return max;
        //end
    }
};

实例2:有n个需要在同一天使用同一个教室的活动a1,a2,…,an,教室同一时刻只能由一个活动使用。每个活动ai都有一个开始时间si和结束时间fi 。一旦被选择后,活动ai就占据半开时间区间[si,fi)。如果[si,fi]和[sj,fj]互不重叠,ai和aj两个活动就可以被安排在这一天。该问题就是要安排这些活动使得尽量多的活动能不冲突的举行。

#include<cstdio>//printf,scanf函数
#include <algorithm>//sort函数
using namespace std;
#define N 100
int M;//活动总数量
//定义类用来存活动的开始时间和结束时间
class Act
{
public:
    int start;
    int end;
};
Act act[N];
//自定义sort的排序标准,此处选择活动的结束时间作为排序标准
bool cmp(Act A, Act B)
{
    return A.end<B.end;
}
//贪心算法的实现
void greedy()
{
    int i=0,k=0;
    int p[10]={0};
    p[k]=i;
    printf("第1个活动安排:开始时间%d,结束时间%d\n",act[i].start,act[i].end);//输出第k=0个活动
    for(int j=1;j<M;j++)
    {
        if(act[j].start>act[i].end)
        {
            i=j;
            p[++k]=j;
            printf("第%d个活动安排:开始时间%d,结束时间%d\n",k+1,act[i].start,act[i].end);//输出第k个活动
        }
    }
}
int main()
{
    scanf("%d",&M);
    printf("the nums of activities:%d\n",M);
    for(int i=0;i<M;i++)
    {
        scanf("%d,%d",&act[i].start,&act[i].end);
        printf("start is %d,end is %d\n",act[i].start,act[i].end);
    }
        sort(act,act+M,cmp);
        greedy();
    return 0;
}

实例3、钱币找零问题,假设1元、2元、5元、10元、20元、50元、100元的纸币分别有c0, c1, c2, c3, c4, c5, c6张。现在要用这些钱来支付K元,至少要用多少张纸币?用贪心算法的思想,很显然,每一步尽可能用面值大的纸币即可。在日常生活中我们自然而然也是这么做的。在程序中已经事先将Value按照从小到大的顺序排好。

#include<iostream>
#include<algorithm>
#include<memory.h>
using namespace std;
const int N=7;
int coun[N]={3,0,2,1,0,3,5};
int value[N]={100,50,20,10,5,2,1};
int solve_num[N]={0};
void solve(int money)
{
    for(int i =0;i<7;i++)
    {
        if((money>value[i])&&(coun[i]>0))
        {
            do{
                money=money-value[i];
                coun[i]--;
                ++solve_num[i];
            }
            while((coun[i]>0)&&(money>=value[i]));
            cout<<value[i]<<"needs"<<solve_num[i]<<endl;
        }
    }
}
int main()
{
    int money;
    cin>>money;
    solve(money);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值