游览世博、钓鱼问题------详细题解

这两个问题很像,都是依次枚举出以每一个地点为终点时的最大值,在从中选取一个最大值

游览世博

题目描述

华华准备去上海世博会游览,但展馆太多,而时间有限,因此他只能选择游览一部分展馆。在世博园区,假设华华想去的所有展馆都在一条直道上,展馆只有大、小两类,参观小展馆需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;
}

猜你喜欢

转载自blog.csdn.net/qq_45721778/article/details/106047934