贪心入门..

贪心入门
贪心就是把一个大的难的问题分解成几个小的容易的问题,贪心上限比较高,但是入门并不是很难(嗯哼)
hdu2037 题目链接没有 hdu进不去了,大概意思就是小明要看电视,每个节目的起止时间不一样,给出节目单编写代码看小明最多能看多少个节目
(小明一个敲代码的天天对着电脑还一次性看这么多眼睛不累迈)
基本思路就是把它们按节目结束的时间排序,然后循环逐一判断上一节目结束时间是否早于下一节目起始时间,是的话小明就可以大喊一声

就决定是你了!

贴代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#define MAX 106
using namespace std;
struct node//定义结构体用来存放起止时间,结构体我自己很少用不太习惯,有点生疏
{
    int b;
    int e;
};
node T[MAX];
bool cmp(node a,node b)
{
    return a.e<b.e;
}//新学的比较函数,比较节目结束的时间,这题的重点代码之一
int main()
{
     int n,i;
     while(scanf("%d",&n)&&n)//也是新学的当n不为0时执行语句
     {
         for(i=0;i<n;i++)
            cin>>T[i].b>>T[i].e;
         sort(T,T+n,cmp);//排个序
         int t=0,k=0;
         for(i=0;i<n;i++)
         {
             if(t<=T[i].b)//判断上一个节目的结束时间是否小于下一个节目的开始时间,这就是这题贪心的重点之一
             {
                 t=T[i].e;
                 k++;//计算用的
             }
         }
         cout<<k<<endl;//ending
     }
}

有 n 个人在一个水龙头前排队接水,假如每个人接水的时间为 T 请编程找出这 n 个人排队的一种顺序,使得 n 个人的平均等待时间最小。

计算的我着实想了很久
这道题有一个地方需要注意。当一共有 n 人排队接水时,第 i 个人接水,后面一共有 n - i 人等待。所以第 i 人的等待时间需要乘以 n - i 再计入总时间。不要每个人的时间只算一次。
贴代码

#include<algorithm>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdio>
#define MAX 1006
using namespace std;

struct code{
    int I;//序号
    int x;//时间
};

code d[MAX];

bool cmp(code a,code b){
    return a.x<b.x;
}

int main(){
    int i,n,T;
    double sum=0;
    cin>>n;
    for(i=1;i<=n;i++){///要从1开始,或者后面输出的时候要记得+1
        cin>>d[i].x;
        d[i].I=i;
    }
    sort(d+1,d+n+1,cmp);//排序
    //最开始想的是按接水时间升序排列就可以了
    //确实是这样的,难的是后面的计算(好吧其实也不难,就是我暂时比较菜罢了)
    //用下结构体吧,要把序号的对应的接水时间绑定,结构体的功能就是这样,反正结构体也不熟,多用几次
    //这道题有一个地方需要注意。当一共有 n 人排队接水时,第 i 个人接水,后面一共有 n - i 人等待。所以第 i 人的等待时间需要乘以 n - i 再计入总时间。不要每个人的时间只算一次。
    ///这里排完序之后直接输出就好了 记得换行啊,
    for(i=1;i<=n;i++){//要从1开始,或者后面输出顺序的时候记得+1
        cout<<d[i].I<<" ";
    }
    cout<<endl;
    for(i=1;i<=n;i++){
        sum=sum+(d[i].x*(n-i));//这里怎么错了这么次啊。。。。。。欲哭无泪
    }
    printf("%.2lf\n",sum/n);//就是这里,算式没错,我居然除了除了2 SOS
}

吃饭吃饭咯

这题解了很久,很容易错,特别是结构体不熟悉的人,看似DP(DP还没怎么学)实则是贪心的题目
部分背包
阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有 N 堆金币,第 i 堆金币的总重量和总价值分别是 m_i,v_i。阿里巴巴有一个承重量为 T 的背包,但并不一定有办法将全部的金币都装进去。他想装走尽可能多价值的金币。所有金币都可以随意分割,分割完的金币重量价值比(也就是单位价格)不变。请问阿里巴巴最多可以拿走多少价值的金币?
所有的金币都可以分割,意思就是每一克的金币价钱都不一定一样,所以需要考虑哪一堆金币的价格比更高,用最少的容量装最贵的金子,所以用一个结构体把每一堆金子的重量、总体价格和价格比都放一起,然后用价格比排序,最后一堆一堆的放进背包里带走。
贴代码

#include<cstring>
#include<iostream>
#include<algorithm>//排序要用的头文件
#include<cstdio>
#define MAX 106
using namespace std;

//价值是v 重量是m x是价格比

struct node{
    int v;
    int m;
    int x;
};

node a[MAX];

bool cmp(node a,node b){
    return a.v*b.m>b.v*a.m;//价格比排序 原型是a.v/a.m>b.v/b.m 
    //简单的的数学知识
    //这样写可以避免出现浮点数(因为前面结构体定义的都是int类型)
}

int main(){
    int N,T;
    double sum=0;//注意一下要记得用浮点
    cin>>N>>T;
       int i;
    for(i=0;i<N;i++){//输入
        cin>>a[i].m>>a[i].v;//结构体真的是有亿点点生疏啊。。。
    }
    sort(a,a+N,cmp);//性价比排序,卡了害,
    for(i=0;i<N;i++){
        //好了我知道问题出在哪里了,还是要用结构体,
        //不然价格比排序不能起到作用,每一堆金币的质量和价值对应的下标不会随着我的排序而变化
        //诶等等,我刚刚看到一个题解用的冒泡???
        //感觉她的应该过不了哇……三个全部分开排序了 每一个下标对应的的性价比价值和重量都有可能不一样,这里应该要把三个关联在一起啊
        //我理解不了了还是用结构体吧
        
        ///这里就是放东西环节
        if(a[i].m<=T){///如果这堆金币放得下就全部放进去
            T-=a[i].m;
            sum+=a[i].v;
        }
        else{///放不下就分开能放多少是多少
            sum+=(double)a[i].v/a[i].m*T;//注意要浮点数转换
            break;
        }
    }
    printf("%.2lf\n",sum);//保留两位输出
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值