AcWing 1262. 鱼塘钓鱼(每日一题)

目录

暴力枚举法:

贪心:


原题链接:1262. 鱼塘钓鱼 - AcWing题库

有 N个鱼塘排成一排,每个鱼塘中有一定数量的鱼,例如:N=5 时,如下表:

鱼塘编号12345
第1分钟能钓到的鱼的数量(1..1000)101420169
每钓鱼1分钟钓鱼数的减少量(1..100)24653
当前鱼塘到下一个相邻鱼塘需要的时间(单位:分钟)3544

即:在第 1 个鱼塘中钓鱼第 1 分钟内可钓到 10 条鱼,第 2分钟内只能钓到 8 条鱼,……,第 5 分钟以后再也钓不到鱼了。

从第 1 个鱼塘到第 2 个鱼塘需要 3 分钟,从第 2 个鱼塘到第 3 个鱼塘需要 5 分钟,……

给出一个截止时间 T,设计一个钓鱼方案,从第 1 个鱼塘出发,希望能钓到最多的鱼。

假设能钓到鱼的数量仅和已钓鱼的次数有关,且每次钓鱼的时间都是整数分钟。

输入格式

共 5 行,分别表示:

第 1 行为 N;

第 2 行为第1 分钟各个鱼塘能钓到的鱼的数量,每个数据之间用一空格隔开;

第 3 行为每过 1 分钟各个鱼塘钓鱼数的减少量,每个数据之间用一空格隔开;

第 4 行为当前鱼塘到下一个相邻鱼塘需要的时间;

第 5 行为截止时间 T。

输出格式

一个整数(不超过2^31−1),表示你的方案能钓到的最多的鱼。

数据范围

1≤N≤100
1≤T≤1000

输入样例:

5
10 14 20 16 9
2 4 6 5 3
3 5 4 4
14

输出样例:

76

暴力枚举法:

由于此题数据量很小可以进行暴力枚举,当前鱼塘可以掉一会时间,当到达转移时间时,可以花费c[i]去转移到下一个鱼塘,获得更多的鱼,dp[i][j]=dp[i+1][k]+dp[i][j-k-c[i]];

#include<iostream>
#include<string>
using namespace std;
int n,t;
bool flag=0;
int a[105],a1[105],b[105],c[105];
int dp[105][1005];
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<=n;i++)cin>>b[i];
	for(int i=1;i<n;i++)cin>>c[i];
	cin>>t;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=t;j++){
			dp[i][j]=dp[i][j-1]+a[i];
			a[i]=max(a[i]-b[i],0);
		}
	}
	for(int i=n-1;i>=1;i--){//逆序枚举鱼塘个数,因为下面要处理第i+1个鱼塘,i+1要先于i更新
		for(int j=t;j>=c[i];j--){//j为总时间,花费最少c[i],用来走到下一个鱼塘
			int maxx=dp[i][j];
			for(int k=0;k<=j-c[i];k++){
            //可以给i+1个分配k个时间,那么剩下j-k-c[i]为第i个鱼塘的时间
				maxx=max(maxx,dp[i+1][k]+dp[i][j-k-c[i]]);
			}
			dp[i][j]=maxx;
		}
	}
	cout<<dp[1][t]<<endl;
	return 0;
}

贪心:

这个题我们可以把一个鱼塘可以钓的鱼数全部列举出来,从中选取k大的数即为答案,这个k又是啥,我们的总时间T可以分为路程时间+钓鱼时间,我们枚举一下最多到哪一个终点,此时路程时间便可以知道,那么钓鱼的时间=总时间T-路程时间,注释附在代码上。

#include<iostream>
#include<cstring>
using namespace std;
const int N=105;
int n,t,res;
int a[N],b[N],c[N],s[N];
//a表示第 1分钟各个鱼塘能钓到的鱼的数量,b表示鱼减少的数量
//c表示到达各个鱼塘时间,s表示在第i个鱼塘钓的时间
int get(int k){//在第k个鱼塘可以钓的鱼数
	return max(0,a[k]-b[k]*s[k]);//初始a[k],每次减少b[k],钓了s[k]分钟
	//所以此时可以在第k个鱼塘钓a[k]-b[k]*s[k]个,但不能小于0
}
//多路归并,每一次寻找可以钓的最大鱼数
int work(int n,int t){//n表示最多移动到第n个鱼塘,t表示钓鱼的时间
	int res=0;
	memset(s,0,sizeof(s));//初始都为0
	for(int i=1;i<=t;i++){//枚举每一分钟
		int m=1;//记录最大下标
		for(int j=2;j<=n;j++){//枚举1-n的鱼塘数
			if(get(m)<get(j)){//第j个鱼塘所获得的鱼数小于第m个鱼塘所获得的鱼数,则更新下标
				m=j;
			}
		}
		res+=get(m);
		s[m]++;//在第m个上钓鱼要花费时间
	}
	return res;
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<=n;i++)cin>>b[i];
	for(int i=2;i<=n;i++){
		cin>>c[i];
		c[i]+=c[i-1];//前缀和求花费移动鱼塘的时间
	}
	cin>>t;
	for(int i=1;i<=n;i++){//枚举第一个鱼塘到第i个鱼塘最大获得多少鱼
		res=max(res,work(i,t-c[i]));//t-c[i]表示总时间减去移动花费的时间,剩下为钓鱼的时间
	}
	cout<<res<<endl;
	return 0;
}

这样时间复杂度会大大优化,如果数据量再大一点,暴力枚举就会寄了

此题贪心思路按照y总的讲解写的,里面涉及了多路归并等算法,此题还有更多解法,不再一一介绍了,文章尚有不足,欢迎大佬们指正。

  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
智慧鱼塘是一款专为鱼塘爱好者设计的手机应用程序。该应用旨在提供鱼塘管理的便利性和智能化功能,帮助用户更好地照顾和管理他们的鱼类。 首先,智慧鱼塘app设计图包含一系列鱼塘管理工具。用户可以通过应用添加他们的鱼塘信息,并对每条鱼进行个体档案管理。通过扫描鱼类标签,用户可以快速查看鱼类的品种、成长记录和健康状态等重要信息。此外,用户还可以记录并跟踪鱼类的食欲、体重和行为习惯,以及鱼塘水质和温度等环境参数。 其次,智能化功能是智慧鱼塘app设计中的重要组成部分。用户可以设置定时喂食功能,让应用在预定的时间自动给鱼类喂食,确保它们的正常生活习惯和营养摄入。此外,如果水质或温度超出理想范围,应用会发出警报提醒用户采取相应的措施,避免鱼类受到不良影响。同时,用户还可以通过智能推荐功能,获得关于鱼类饲养和鱼塘管理的专业建议。 最后,智慧鱼塘app设计图还提供了一个社交互动平台。用户可以创建个人资料,并与其他鱼塘爱好者分享自己的鱼塘经验、发现和问题。用户可以发布图片或视频,展示自己的鱼类和鱼塘,与其他用户进行交流和互动。这个平台也可以用于寻求专家或其他用户的建议和意见,共同解决鱼塘管理中的问题。 总之,智慧鱼塘app设计图旨在提供鱼塘管理的便利性和智能化功能。通过提供鱼类个体档案管理、智能化喂食和报警功能,以及社交互动平台,该应用帮助用户更好地照顾和管理他们的鱼塘,促进鱼塘爱好者之间的交流和分享。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摆烂小白敲代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值