uva 757 Gone Fishing (贪心)

uva 757 Gone Fishing

John is going on a fishing trip. He has h hours available ( ), and there are
n lakes in the area ( ) all reachable along a single, one-way road. John starts at lake 1, but he can finish at any
lake he wants. He can only travel from one lake to the next one, but he does not have to stop at any lake unless he wishes to. For each
, the number of 5-minute intervals it takes to travel from lake
i to lake i + 1 is denoted ti ( ). For example,
t3 = 4 means that it takes 20 minutes to travel from lake 3 to lake 4.

To help plan his fishing trip, John has gathered some information about the lakes. For each lake
i, the number of fish expected to be caught in the initial 5 minutes, denoted
fi ( ), is known. Each 5 minutes of fishing decreases the number of fish expected to be caught in the
next 5-minute interval by a constant rate of di ( ). If the number of fish expected to be caught in
an interval is less than or equal to di, there will be no more fish left in the lake in the next interval. To simplify the planning, John assumes that no one else will be fishing at the lakes to affect the number of fish he expects
to catch.

Write a program to help John plan his fishing trip to maximize the number of fish expected to be caught. The number of minutes spent at each lake must be a multiple of 5.

Input

You will be given a number of cases in the input. Each case starts with a line containing
n. This is followed by a line containing h. Next, there is a line of
n integers specifying fi ( ), then a line of
n integers di ( ), and finally, a line of
n - 1 integers ti ( ). Input is terminated by a case in which
n = 0.

Output

For each test case, print the number of minutes spent at each lake, separated by commas, for the plan achieving the maximum number of fish expected to be caught (you should print the entire plan on one line even if it exceeds 80 characters). This is followed
by a line containing the number of fish expected. If multiple plans exist, choose the one that spends as long as possible at lake 1, even if no fish are expected to be caught in some intervals. If there is still a tie, choose the one that spends as long as
possible at lake 2, and so on. Insert a blank line between cases.

Sample Input

2
1
10 1
2 5
2
4
4
10 15 20 17
0 3 4 3
1 2 3
4
4
10 15 50 30
0 3 4 3
1 2 3
0

Sample Output

45, 5
Number of fish expected: 31

240, 0, 0, 0
Number of fish expected: 480

115, 10, 50, 35
Number of fish expected: 724

题目大意:

每组样例包括5各部分:

1)鱼塘数 n

2)总时间 h(小时)

3)n 个鱼塘,每个鱼塘中初始鱼的产量(每5分钟可以钓上的鱼的数量)

4)n 个鱼塘,每个鱼塘鱼的损耗速度(每在该鱼塘钓鱼5分钟,鱼的产量减少的数量)

5)n 个鱼塘之间的路程的耗时(单位为5分钟)

要求在总时间 h 内可以钓上的最多的鱼的数量,和在每一个鱼塘停留的时间。当到达下一个鱼塘时,不能返回上一个鱼塘。

解题思路:先要对鱼塘之间路程的耗时进行处理,要将其转变为从第一个鱼塘到第 i 个鱼塘所需的时间。

枚举只在前 i 个鱼塘钓鱼的 n 种情况,这样  只在前 i 个鱼塘钓鱼的钓鱼时间 = 总时间 - 第一个鱼塘到第 i 个鱼塘所需时间,然后在前 i 个鱼塘中找出当前鱼产量最多的鱼塘,在此钓鱼,然后重复之前的过程,直到前 i 个鱼塘无鱼可钓或者时间耗尽。这样,n 种情况中的最大值,就是可以钓起的最多鱼的数量。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int n, h, f[250], d[250], t[250], ans, rec[250], recA[250], temp[250];
int find(int x) {
	int num = 0, id;
	for (int i = 0; i <= x; i++) {
		if (temp[i] > num) {
			num = temp[i];
			id = i;
		}
	}
	if (num) {
		return id;
	}
	else return -1;
}
int main() {
	int flag = 0;
	while (scanf("%d", &n) == 1, n) {
		if (flag) printf("\n");
		flag = 1;
		int H;
		scanf("%d", &H);
		h = H * 12;
		for (int i = 0; i < n; i++) {
			scanf("%d", &f[i]);
		}
		for (int i = 0; i < n; i++) {
			scanf("%d", &d[i]);
		}
		t[0] = 0;
		for (int i = 1; i < n; i++) {
			scanf("%d", &t[i]);
			t[i] += t[i - 1];
		}
		memset(recA, 0, sizeof(recA));
		ans = 0;
		for (int i = 0; i < n; i++) { //枚举n种情况:从第一个鱼塘到第i个鱼塘
			int time = h - t[i], sum = 0;
			if (time <= 0) break;
			memcpy(temp, f, sizeof(f));
			memset(rec, 0, sizeof(rec));
			while (time) {
				int id = find(i); //find找出前i个鱼塘中鱼最多的鱼塘
				if (id < 0) break;
				sum += temp[id];
				temp[id] -=	d[id];
				time--;
				rec[id]++;
			}
			if (time > 0) { //当前i个鱼塘都无鱼可钓,且还有剩余时间,留在第一个鱼塘
				rec[0] += time;
			}
			if (sum > ans) {
				ans = sum;
				memcpy(recA, rec, sizeof(rec));
			}
		}
		if (ans) {
			printf("%d", recA[0] * 5);
		}
		else printf("%d", h * 5); //当无鱼可钓的时候也要停留在第一个鱼塘,样例会卡这里
		for (int i = 1; i < n; i++) {
			printf(", %d", recA[i] * 5);
		}
		printf("\nNumber of fish expected: %d\n", ans);
	}
	return 0;
}
时间: 2024-12-16 16:19:01

uva 757 Gone Fishing (贪心)的相关文章

UVA 757 Gone Fishing

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=9&problem=698&mosmsg=Submission+received+with+ID+19496827 利用枚举和贪心来计算.枚举在每个湖stop fishing的情况,在每种情况下,贪心算法得出能钓得最多鱼的数目.因为题目要求:If multiple

UVA 10317 - Equating Equations 贪心 dfs

UVA 10317 - Equating Equations 贪心 dfs ACM 题目地址:UVA 10317 - Equating Equations 题意: 给一个等式,但是这个等式不一定是正确的,要你对等式中的数字重新排序,使得等式成立.等式只有+和-,数字个数小于16. 分析: 以a + b - c = d - e为例子. 1. 我们把等式右边的各项都换到左边,a + b - c - d + e = 0 2. 把+项和-项放一起,就变成(a + b + e) - (c + d) = 0

UVA 12130 - Summits(BFS+贪心)

UVA 12130 - Summits 题目链接 题意:给定一个h * w的图,每个位置有一个值,现在要求出这个图上的峰顶有多少个.峰顶是这样定义的,有一个d值,如果一个位置是峰顶,那么它不能走到不大于该峰顶高度 - d的位置,如果满足这个条件下,并且无法走到更高的山峰,那么它就是峰顶 思路:利用贪心的策略,把所有点丢到优先队列,每次取出最高的峰值开始找,进行广搜,搜的过程中记录下最大值的点的个数,如果这个是峰顶,就加上这个数.判断是不是峰顶的方法为,如果广搜过程中,不会找到一个点的能到的最高峰

uva757 - Gone Fishing(贪心)

题目:uva757 - Gone Fishing(贪心) 题目大意:有N个湖泊只有一条通路将这些湖泊相连.每个湖泊都会给最开始5分钟间隔内可以调到的鱼(f),然后给每过5分钟减少的鱼的数量(d),如果当前的鱼少于等于减少的数量,说明在下个5分钟没有鱼.还有过每条道路的所要耗费的时间(N-1),时间都是以5分钟为单位的.渔者可以在任意一个湖泊钓鱼,但是起始位置是在湖泊1.问H小时后,渔者怎样合理的在每个湖泊分配时间,可以得到的鱼最多.如果得到最多的鱼的方式有多种,则取在前面的湖泊耗时最久的那一种.

POJ-1042 Gone Fishing (贪心法求最佳钓鱼方案

Gone Fishing Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 28075   Accepted: 8371 Description John is going on a fishing trip. He has h hours available (1 <= h <= 16), and there are n lakes in the area (2 <= n <= 25) all reachab

uva 1534 - Taekwondo(dp+贪心)

题目连接:uva 1534 - Taekwondo 题目大意:有两组什么东西,题目背景有点忘记了,就是给出两组数,两组个数分别为n,m,要求找出min(n,m)对数,每个数最多最多选一次,使得这min(n,m)对数ai,bi,ai-bi的绝对值之和最小. 解题思路:贪心,将两组数分别排序,然后dp[i][j]表示i对,匹配到j时候的最优解. #include <cstdio> #include <cstring> #include <cmath> #include &l

UVA 1422 - Processor (二分+贪心+优先队列)

先对开始时间进行排序,在利用优先队列是结束时间早点先出队: 因为时间只有20000,我们可以去枚举每个单位时间,看要给分配给那个任务, 如果某个时间队列中还有结束时间大于枚举的时间,就跳出判断是在mid的右边. #include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> #include<stdlib.h> #include<math.h> #

uva 1372 - Log Jumping(贪心)

题目链接:uva 1372 - Log Jumping 题目大意:给出n,k,表示有n个木板和长度均为k,现在给出所有木板的左边位置,如果两块木板有重叠,那么就可以在两块木板之间移动,问说最多能形成的最大块数的环. 解题思路:将木块按照左边界排序,每次如果i块板和i-1,i-2有重叠,那么i块板也可以加入环. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; co

uva 10020- Minimal coverage (贪心思想 简单区间覆盖)

题目大意:给出一个范围M,然后给出若干的区间,以0 0 终止, 要求用最少的区间将0 ~M 覆盖,输出最少个数以及方案. 解题思路:典型的区间覆盖问题,算法竞赛入门经典P154上有讲. /*author: charkj_z */ /*time: 0.108s */ /*rank: 674 */ /*为什么不把没用的地方去掉? 因为去掉了我觉得不像我能写出来的*/ /*Ac code : */ #include<stdio.h> #include<string.h> #include