uva 757 Gone Fishing(贪心)

题目连接:757 - Gone Fishing


题目大意:有N个湖, 每个湖在单位时间内可以钓到s[i]条鱼, 但是每在这个湖钓一次鱼,下次钓到的鱼就会减少d[i]只(每次, 直到可以钓到的鱼数为0), 现在给出限定时间,以小时的形式, 题目中的单位时间为5分钟,输出的时候要转换成分钟。然后每个湖之间有一定的距离(距离给出的是该路程所需要的单位时间数)。要求在给定的时间钓到最多的鱼,并输出方案。(ps, 只能一直往下个湖泊移动, 不能回到原先的湖泊)。


输入部分:n(湖泊数, 为0时终止), h(限定时间,小时), s[i](n个数,为对应湖泊当前每次可钓到的鱼数), d[i](n个数,为每个湖泊钓一次之后钓鱼数减少的量),dist[i](n - 1个数,为两两湖泊之间移动所需的单位时间,注意这里是单位时间)


输出部分:rec[i](n 个数,对应为在该湖泊呆的时间),Max(可以调到的最大鱼量),每两组数据间空行。


解题思路:贪心的方法。

1、在哪个湖钓的鱼多,肯定先在哪一个湖泊钓,因为你在这个湖泊钓的时候其它湖泊的鱼并不会减少, 所以并不会影响到下次钓鱼时最大量的迁移。

2、对于时间,是题目已经给定好的, 但是每两个湖泊之间移动需要时间, 如果移动,总的钓鱼时间会减少,所以如何解决移动与否是题目的关键。

3、其实题目中给出的不能返回上一个湖泊是用来误导大家的, 因为每个湖泊鱼量减少是不相关的,也就是独立的问题,所以我们只需要考虑说钓鱼的这个人最后在哪个湖泊停止就好,枚举出n种可能,每种可能有它自己的最大值,在这n种情况的最大值中的最大值就是最优解。

4、先在问题转换成钓鱼的人在1-i个湖泊钓鱼的最大鱼量,那也就是默认钓鱼的人一定会走到第i个湖,即,走的路程时间是一定要用的,所以可以拿总得时间减掉路程的时间所得到的time就是他可以钓鱼的时间了,而且因为路程已经走过了, 只要到纯的贪心拿最多的就好了,转化成实际问题只是把走路和钓鱼的时间调换考虑了一下,并不影响结果。


#include <stdio.h>
#include <string.h>
const int N = 1010;
int h, n, Max, s[N], d[N], dist[N];
int now[N], rec[N], vis[N];

void input() {
    int t;
    Max = 0;
    memset(s, 0, sizeof(s));
    memset(d, 0, sizeof(d));
    memset(dist, 0, sizeof(dist));
    memset(rec, 0, sizeof(rec));
    scanf("%d", &h);

    for (int i = 0; i < n; i++)
	scanf("%d", &s[i]);

    for (int i = 0; i < n; i++)
	scanf("%d", &d[i]);

    for (int i = 1; i < n; i++) {
	scanf("%d", &dist[i]);
	dist[i] += dist[i - 1];
    }
}

void output() {
    if (Max)
	printf("%d", rec[0] * 5);
    else
	printf("%d", h * 60);
    for (int i = 1; i < n; i++)
	printf(", %d", rec[i] * 5);
    printf("\nNumber of fish expected: %d\n", Max);
}

int find(int m) {
    int tmp = 0, id;
    for (int i = 0; i <= m; i++)
	if (tmp < now[i]) {
	    tmp = now[i];
	    id = i;
	}
    return tmp ? id : -1;
}

int solve() {
    int sum, time, id;

    for (int i = 0; i < n; i++) {
	time = h * 12 - dist[i];
	if (time <= 0)	break;
	memcpy(now, s, sizeof(s));
	memset(vis, 0, sizeof(vis));
	sum = 0;

	while (time > 0) {
	    id = find(i);
	    if (id < 0) break;
	    time--;
	    sum += now[id];
	    now[id] -= d[id];
	    vis[id]++;
	}
	if (time > 0)
	    vis[0] += time;

	if (sum > Max) {
	    Max = sum;
	    memcpy(rec, vis, sizeof(vis));
	}
    }
}

int main() {
    int t, flag = 1;
    while (scanf("%d", &n) && n) {
	input();
	if (flag)   flag = 0;
	else 
	    printf("\n");
	solve();
	output();
    }
    return 0;
}

你可能感兴趣的:(uva 757 Gone Fishing(贪心))