贪心

贪心算法
每一步行动总是按某种指标选取最优的操作来进行,
该指标只看眼前,并不考虑以后可能造成的影响。
贪心算法需要证明其正确性
4110:圣诞老人的礼物-Santa Clau’s Gifts
查看 提交 统计 提示 提问
总时间限制: 1000ms 内存限制: 65536kB
描述
圣诞节来临了,在城市A中圣诞老人准备分发糖果,现在有多箱不同的糖果,每箱糖果有自己的价值和重量,每箱糖果都可以拆分成任意散装组合带走。圣诞老人的驯鹿最多只能承受一定重量的糖果,请问圣诞老人最多能带走多大价值的糖果。

输入
第一行由两个部分组成,分别为糖果箱数正整数n(1 <= n <= 100),驯鹿能承受的最大重量正整数w(0 < w < 10000),两个数用空格隔开。其余n行每行对应一箱糖果,由两部分组成,分别为一箱糖果的价值正整数v和重量正整数w,中间用空格隔开。
输出
输出圣诞老人能带走的糖果的最大总价值,保留1位小数。输出为一行,以换行符结束。
样例输入
4 15
100 4
412 8
266 7
591 2
样例输出
1193.0

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
struct candy
{
    int w;
    int v;
    bool operator< (const candy &c) const  //注意格式const
    { return double(v)/w>double(c.v)/c.w;}  // v,w,是这个的,而c.v,c.w,是另一个的
    两个相比较,> 是按大的在前面降序;< 是按小的在前面,升序
}cands[105];
int main()
{
    int n,W;
    int i;
    scanf("%d%d",&n,&W);//有无空格无碍
    for (i=0;i<n;i++)
    {
        scanf("%d %d",&cands[i].v,&cands[i].w);
    }
    sort(cands,cands+n);//排序,按价值大的在前
    int talw=0;
    double talv=0;//输出是按保留一位小数
    for (i=0;i<n;i++)
    {
        if (talw+cands[i].w<=W)//现在的总重量还没超过重量的要求
        {
            talw+=cands[i].w;//对重量,价值,加
            talv+=cands[i].v;
        }
        else
        {
            talv=cands[i].v*double(W-talw)/cands[i].w+talv;//在所剩下还能带走的,占这一整箱的价值比重
            break;//一定要跳出,不然会对下一次再加
        }
    }
    printf("%.1f",talv);
    return 0;
}

4151:电影节
查看 提交 统计 提示 提问
总时间限制: 1000ms 内存限制: 65536kB
描述
大学生电影节在北大举办! 这天,在北大各地放了多部电影,给定每部电影的放映时间区间,区间重叠的电影不可能同时看(端点可以重合),问李雷最多可以看多少部电影。

输入
多组数据。每组数据开头是n(n<=100),表示共n场电影。
接下来n行,每行两个整数(0到1000之间),表示一场电影的放映区间
n=0则数据结束
输出
对每组数据输出最多能看几部电影
样例输入
8
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
0
样例输出
3
运用sort 但添加了重载
bool operator <(const 结构体名(当前) &另一个)const
{ return 变量<另一个.变量;} 这是按从小到大排

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
struct film
{
    int s;
    int e;
    bool operator <(const film &f)const
    { return e<f.e;}//按结束时间从小到大排
}fils[105];
int main()
{
    int n;
    int num,pre;
    while(1)
    {
        int i;
        scanf("%d",&n);
        if (n==0) break;
        for (i=0;i<n;i++)
        cin>>fils[i].s>>fils[i].e;
        sort(fils,fils+n);//小到大,结束时间
        num=1,pre=fils[0].e;//第一部电影肯定看,结束时间最早的
        for(i=1;i<n;i++)
        {
            if (fils[i].s>=pre)//当前的开始时间比前一个的结束时间晚
            {
                num++;
                pre=fils[i].e;//改变前一场看的电影
            }
        }
        printf("%d\n",num);
    }
    return 0;
}

例题: Stall Reservations(POJ 3190)
有 n头牛(1<=n<=50,000)要挤奶。给定每头牛挤奶的时间区
间[A,B] (1<=A<=B<=1,000,000,A,B为整数)。
牛需要呆畜栏里才能挤奶。一个畜栏同一时间只能容纳一头牛。
问至少需要多少个畜栏,才能完成全部挤奶工作,以及每头牛都
放哪个畜栏里(Special judged)
去同一个畜栏的两头牛,它们挤奶时间区间哪怕只在端点重合也
是不可以的。

Description
Oh those picky N (1 <= N <= 50,000) cows! They are so picky that each one will only be milked over some precise time interval A..B (1 <= A <= B <= 1,000,000), which includes both times A and B. Obviously, FJ must create a reservation system to determine which stall each cow can be assigned for her milking time. Of course, no cow will share such a private moment with other cows.
Help FJ by determining:
The minimum number of stalls required in the barn so that each cow can have her private milking period
An assignment of cows to these stalls over time
Many answers are correct for each test dataset; a program will grade your answer.
Input
Line 1: A single integer, N

Lines 2..N+1: Line i+1 describes cow i’s milking interval with two space-separated integers.
Output

Line 1: The minimum number of stalls the barn must have.

Lines 2..N+1: Line i+1 describes the stall to which cow i will be assigned for her milking period.
Sample Input

5
1 10
2 4
3 6
5 8
4 7
Sample Output

4
1
2
3
2
4

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>//用到优先队列
#include <cstring>
#include <vector>
#include <stdlib.h>
using namespace std;
struct cowt
{
    int start;int end;
    int no;
    bool operator <(const cowt & c) const//注意const
    { return start<c.start;}//开始时间早的在前面,牛先入栏
}cows[50005];
struct Stall
{
    int end;
    int no;
    bool operator <(const Stall &s) const
    { return end>s.end;}//优先队列中,小的排在前面时,要用 > ,与sort重载相反
    Stall(int e,int n):end(e),no(n){ } //记住形式
    //名  (变量1,变量2) : 结构体变量(1),结构体变量(2){  }  
};
int a[50005];//栏的数
int main()
{
    int n,i;
    scanf("%d",&n);
    for (i=0;i<n;i++)
    {
        scanf("%d %d",&cows[i].start ,&cows[i].end );
        //cin>>cows[i].start >>cows[i].end;//c++输入
        cows[i].no=i;//对于每一头牛进行编号,因为要记录每头牛进入的栏的号码
    }
    sort(cows,cows+n);//按照开始时间早的排
    int tal=0;//栏的总数
    priority_queue<Stall> pq;//建一个优先队列pq
    for (i=0;i<n;i++)
    {
        if(pq.empty() )//队列中为空,没有能放牛的栏
        {
            tal++;//栏的数增加
            pq.push(Stall(cows[i].end,tal));//将该牛压入队列中,牛结束时间,栏的编号
            a[cows[i].no]=tal;//这头牛的栏的,用数组存储
        }
        else //队列中不为空
        {
            Stall at=pq.top();//队列中第一个拿出来,但是复制出来的,原来的并未删除
            //复制给 at 存储
            if (at.end<cows[i].start)//队列中第一个牛的结束时间比当前牛的开始时间小(早)
            {
                pq.pop();//将第一个删除
                a[cows[i].no]=at.no;//牛的栏编号存入数组
                pq.push(Stall(cows[i].end,at.no));\\将当前牛压入队列
            }
            else//队列中第一个结束时间比当前牛的开始时间(大)晚
            {
                tal++;增加栏的数
                pq.push(Stall(cows[i].end,tal));
                a[cows[i].no]=tal;
            }
        }
    }
    printf("%d\n",tal);
    for (i=0;i<n;i++)
        printf("%d\n",a[i]);//将牛的栏编号输出
    system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
贪心算法是一种基于贪心思想的算法,它在每一步选择中都采取当前状态下最优的选择,从而希望最终得到全局最优解。贪心算法通常可以用来解决一些最优化问题,比如最小生成树、背包问题、最短路径等。 贪心算法的实现步骤一般如下: 1. 定义问题贪心策略。 2. 根据贪心策略,选择当前状态下的最优解。 3. 更新问题的状态,继续步骤 2 直到达到终止条件。 需要注意的是,贪心算法并不是所有问题都能使用的算法。对于某些问题贪心算法可能得到的不是全局最优解,而是局部最优解。因此,在使用贪心算法时,需要保证问题具有贪心选择性质和无后效性质。 下面以一个简单的例子来说明贪心算法的应用。 给定一个数组,每个元素表示一个活动的结束时间和开始时间。你作为一个主办人,需要在这些活动中选择尽可能多的活动进行安排,使得不同的活动之间不会产生时间冲突。求最多能安排多少个活动。 示例代码: ```csharp public class Activity { public int start; public int end; public Activity(int start, int end) { this.start = start; this.end = end; } } public int MaxActivities(Activity[] activities) { int count = 0; int currentEnd = 0; Array.Sort(activities, (a, b) => a.end - b.end); foreach (Activity activity in activities) { if (activity.start >= currentEnd) { count++; currentEnd = activity.end; } } return count; } ``` 在这个示例代码中,我们定义了一个 `Activity` 类来表示活动的开始时间和结束时间。然后,我们通过贪心策略来选择活动,即每次选择结束时间最早的活动。具体实现中,我们将活动按照结束时间从小到大排序,然后依次选择活动,如果当前活动的开始时间大于等于前一个活动的结束时间,则可以选择该活动。最后返回选择的活动数即可。 时间复杂度为 O(n log n),其中 n 是活动数。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值