java买房子钓鱼,AcWing 1262. 鱼塘钓鱼(Java 贪心 Or 优先队列)

算法1 贪心

先考虑最远到哪个鱼塘,把路上的时间预先减掉,剩下的就是完全用于钓鱼的时间注意这里不用考虑折返的情况,因为如果折返前一个池塘钓鱼可以得到更优解,那么完全可以在之前就接着钓

因为一分钟计算一次鱼的数量,而每个鱼塘在第几分钟能钓到的鱼数量是可以确定的,且时间越靠前的数量越多,按样例打个表格

5c00da71b55f092aafe2a0ce975283b2.png

记完全用于钓鱼的时间为$t$,因为所用到的鱼塘的路程耗费时间已经是减过的,而一分钟钓一次鱼,所以只需在用到的池塘选择不多于$t$个的前几个数,它们的总和就是最终能钓到的鱼总数注意是每个池塘的前几个数,而且连续,因为有时间关系

实际上,计算的是总和,所选的数应尽可能大,而越靠前的数值越大,最优解也不会存在不连续的情况

无关顺序,取最大的前几个,因此考虑使用优先队列,或者放进ArrayList再进行排序

虽然用的是优先队列,但是时间复杂度并没有什么优化,还不如ArrayList+排序,有优化的优先队列需要存当前数值和衰减速度

代码

import java.util.*;

import java.lang.*;

public class Main {

static Scanner scanner = new Scanner(System.in);

static int n, T, N = 110; // 鱼塘个数 截止时间

static int[] a = new int[N], da = new int[N], ta = new int[N]; // 初始个数 衰减速度 移动时间

public static void main(String[] args) {

PriorityQueue pq = new PriorityQueue<>((o1, o2) -> o2 - o1); // 大根堆

n = scanner.nextInt();

for (int i = 1; i <= n; i++) a[i] = scanner.nextInt();

for (int i = 1; i <= n; i++) da[i] = scanner.nextInt();

for (int i = 1; i < n; i++) ta[i] = scanner.nextInt();

T = scanner.nextInt();

int res = 0;

for (int k = 1; k <= n; k++) { // 枚举最远到达的鱼塘

int t = T, total = 0;

for (int i = 1; i < k; i++) t -= ta[i]; // 计算余下时间 这里可以用前缀和优化

for (int i = 1; i <= k; i++)

for (int j = a[i]; j > 0; j -= da[i]) pq.add(j); // 加入优先队列

while (t-- > 0 && !pq.isEmpty()) total += pq.poll(); // 获取不超过t个的前几个数

pq.clear(); // 一轮枚举 清空队列

res = Math.max(res, total); // 多种方案取最大值

}

System.out.println(res);

}

}

算法2 优先队列

思路同上,发挥优先队列的优势,在添加鱼塘可获得的鱼总数时,只放入所有能到达的鱼塘当前分别可获得的鱼条数

每次同样取最大的一个数,但现在省略了枚举,且队列的元素个数较少,访问速度快

代码

import java.util.*;

import java.lang.*;

public class Main {

static Scanner scanner = new Scanner(System.in);

static class Pair {

public int l, r;

public Pair(int l, int r) {

this.l = l;

this.r = r;

}

}

static int n, T, N = 110; // 鱼塘个数 截止时间

static int[] a = new int[N], da = new int[N], ta = new int[N]; // 初始个数 衰减速度 移动时间

public static void main(String[] args) {

PriorityQueue pq = new PriorityQueue<>((o1, o2) -> o2.l - o1.l); // 大根堆

n = scanner.nextInt();

for (int i = 1; i <= n; i++) a[i] = scanner.nextInt();

for (int i = 1; i <= n; i++) da[i] = scanner.nextInt();

for (int i = 2; i <= n; i++) ta[i] = ta[i - 1] + scanner.nextInt(); // 优化为前缀和

T = scanner.nextInt();

int res = 0;

for (int k = 1; k <= n; k++) { // 枚举最远到达的鱼塘

int t = T - ta[k], total = 0;

for (int i = 1; i <= k; i++) pq.add(new Pair(a[i], da[i])); // 添加鱼塘初始值

while (t > 0) {

Pair temp = pq.poll();

total += temp.l; // 取最大的一个数 加到总和 并更新当前获得值 添加回队列

pq.add(new Pair(Math.max(0, temp.l - temp.r), temp.r));

t--; // 每钓上一次鱼 时间-1

}

pq.clear(); // 枚举完一轮 清空队列

res = Math.max(res, total);

}

System.out.println(res);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值