这两个问题很像,都是依次枚举出以每一个地点为终点时的最大值,在从中选取一个最大值
游览世博
题目描述
华华准备去上海世博会游览,但展馆太多,而时间有限,因此他只能选择游览一部分展馆。在世博园区,假设华华想去的所有展馆都在一条直道上,展馆只有大、小两类,参观小展馆需30分钟,参观大展馆要60分钟。已知:从起点到各展馆的时间及展馆的大小。请问:华华最多能够参观多少个展馆。
输入
华华准备去上海世博会游览,但展馆太多,而时间有限,因此他只能选择游览一部分展馆。在世博园区,假设华华想去的所有展馆都在一条直道上,展馆只有大、小两类,参观小展馆需30分钟,参观大展馆要60分钟。已知:从起点到各展馆的时间及展馆的大小。请问:华华最多能够参观多少个展馆。
输入
n s(展馆个数n<=100,游览时间s为整数分钟)
n个整数(表示从起点到各展馆所需要的时间,以空格相隔)
n个整数(表示各展馆的大小,1为小展馆,2为大展馆,以空格相隔)
输出
华华能够参观的最多展馆数
样例输入
5 200
30 120 100 75 50
2 1 2 1 1
样例输出
3
(即:参观1、4、5号展馆,总共用时195分钟
题解
这是一个贪心题,我们需要先将展馆位置从大到小排序,依次枚举以各个展馆为终点时的方案,如果以这个展馆为终点,那么我们途经的所有展馆都可以选择参观或者不参观,然后应该先选择从小展馆参观,再选择大展馆参观,使得总参观展馆数最大
代码
#include<iostream>
#include<algorithm>
using namespace std;
//记录世博会的所需时间和大小
struct v
{
int time;
int size;
}visit[15000];
bool cmp(v a, v b)
{
return a.time<b.time;
}
int main()
{
int n,s,x,maxx=0,temp=0,count=0,total;
cin>>n>>total;
for(int i=1;i<=n;i++) cin>>visit[i].time;
for(int i=1;i<=n;i++) cin>>visit[i].size;
//进行排序
sort(visit+1,visit+1+n,cmp);
//依次枚举以各个展馆为终点时的方案
for(int i=1;i<=n;i++)
{
temp=0,count=0;
//先参观小展馆
for(int j=1;j<=i;j++)
{
if(visit[j].size==1&&count+30+visit[i].time<=total)
{
count+=30;
temp++;
}
}
//再参观大展馆
for(int j=1;j<=i;j++)
{
if(visit[j].size==2&&count+60+visit[i].time<=total)
{
count+=60;
temp++;
}
}
maxx=max(maxx,temp);
}
cout<<maxx<<endl;
return 0;
}
钓鱼问题
题目描述
在一条水平路边,有 nn 个钓鱼湖,从左到右编号为 1,2,…,n1,2,…,n。佳佳有 HH 个小时的空余时间,他希望利用这个时间钓到更多的鱼。他从 11 出发,向右走,有选择的在一些湖边停留一定的时间(是 55 分钟的倍数)钓鱼。最后在某一个湖边结束钓鱼。佳佳从第 ii 个湖到第 i+1i+1 个湖需要走 5\times T_i5×Ti 分钟路,还测出在第 ii 个湖停留,第一个 55 分钟可以钓到 F_iFi 条鱼,以后每再钓 55 分钟,可以钓到的鱼量减少 D_iDi,若减少后的鱼量小于 00,则减少后的鱼量为 00 。为了简化问题,佳佳假定没有其他人钓鱼,也没有其他因素影响他钓到期望数量的鱼。请编程求出佳佳最多能钓鱼的数量。
输入
第一行一个整数 n,表示湖的个数
第二行一个整数 H,表示佳佳的空闲时间
第三行有 n 个整数,依次表示每个湖第一个 55 分钟能钓到鱼的数量
第四行有 n 个整数,依次表示以后的每5分钟钓鱼数量比前一个 55 分钟钓鱼数量减少的数量
第五行有 n-1 个整数,Ti 表示由第 i 个湖到第 i+1 个湖需要花 5×Ti 分钟的路程
输出
输出只有一行,表示佳佳最多能钓鱼的数量
样例输入
3
1
4 5 6
1 2 1
1 2
样例输出
35
样例解释
在第 11 个湖钓 15 分钟,共钓得 4+3+2=94+3+2=9 条鱼;
在第 22 个湖钓 10 分钟,共钓得 5+3=85+3=8条鱼;
在第 33 个湖钓 20 分钟,共钓得 6+5+4+3=186+5+4+3=18 条鱼;
从第 11 个湖到第 22 个湖,从第 22 个湖到第 33 个湖,共用时间 1515 分钟,共得 3535 条鱼,并且这是最多的数量。
题解
这道题是一个贪心问题,依次枚举只走到每一个池塘的情况下,所能掉到的最多鱼,进行比较,取最大值就行
#include<iostream>
#include<algorithm>
using namespace std;
struct l
{
int num;
int jian;
};
struct lt
{
int num;
int jian;
};
bool cmp(lt l1,lt l2)
{
return l1.num>l2.num;
}
int main()
{
int time,t[110],i,j,n,maxx,count,sum,fish,k;
l lake[110];
lt laketemp[110];
while(cin>>n)
{
cin>>time;
time*=60;//以分钟记
//依次表示每个湖第一个5分钟能钓到鱼的数量
for(i=1;i<=n;i++)
{
cin>>lake[i].num;
laketemp[i].num=lake[i].num;
}
//依次表示以后的每5分钟钓鱼数量比前一个5分钟钓鱼数量减少的数量
for(i=1;i<=n;i++)
{
cin>>lake[i].jian;
laketemp[i].jian=lake[i].jian;
}
for(i=2;i<n+1;i++)//在路上花费的时间
{
cin>>t[i];
t[i]*=5;
}
t[1]=0;
maxx=0;
//sort(laketemp+1,laketemp+n,cmp);//测验
//枚举以每一个湖为结束点的最大钓鱼量
for(i=1;i<=n;i++)
{
sum=0,count=time;
//减去花费在路上的时间
for(j=1;j<=i;j++) count-=t[j];
count/=5;//钓多少次鱼
//初始化数据,确保每一次的数据都是原始数据
for(k=1;k<=i;k++)
{
laketemp[k].jian=lake[k].jian;
laketemp[k].num=lake[k].num;
}
//先把剩余鱼多的排在前面
sort(laketemp+1,laketemp+i+1,cmp);
fish=laketemp[1].num;
while(count>0&&fish>0)//次数和鱼数都大于0
{
//总钓鱼数相加
sum+=laketemp[1].num;
//减去5分钟内的鱼量
laketemp[1].num-=laketemp[1].jian;
//再次更新
sort(laketemp+1,laketemp+i+1,cmp);
fish=laketemp[1].num;
count--;
}
maxx=max(maxx,sum);
}
//取地最大值
cout<<maxx<<endl;
}
return 0;
}