贪心入门
贪心就是把一个大的难的问题分解成几个小的容易的问题,贪心上限比较高,但是入门并不是很难(嗯哼)
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);//保留两位输出
}