贪心算法
每一步行动总是按某种指标选取最优的操作来进行,
该指标只看眼前,并不考虑以后可能造成的影响。
贪心算法需要证明其正确性
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;
}