LightOJ - 1106 - Gone Fishing (贪心+枚举+堆,DP)

题目链接 :Gone Fishing

转载链接 :大神链接


题意

给出n个湖,John最开始在第一个湖并且有h个小时的时间,每个湖初始可以钓到f只鱼,每单位时间可以钓到的鱼减少d只(单位时间为5分钟,不足d只时减少为0),从第i个湖到第i+1个湖需要t[i]单位时间。求最多能够钓到鱼的数量和在每个湖花费的时间。
数据
输入第一行表示数据组数 T,T <= 100
对于每组测试数据,第一行为n和h,2 <= n <= 25,1 <= h <= 16
接下来一行为n个整数f[i],0 <= f[i] <= 1000
接下来一行为n个整数d[i],0 <= d[i] <= 1000
接下来一行为n-1个整数t[i],0 < t[i] < 192


思路

​ 贪心,堆优化(由于数据比较小,可以直接暴力)
首先我们可以枚举要走过湖泊数X,然后算出从1到X的时间。那么在这个前提下,我们可以认为fisher可以从一个湖泊“瞬间转移”到另一个湖泊,即在任意一个时刻可以从1到X中任选一个钓鱼。
此时,走路的时间确定了,钓鱼的次数就确定了(每次5分钟),然后每次都选取f[i]最大的钓,这种贪心的思想最终能够得到一个钓鱼序列。
你可能会跟我一样有一个疑问:因为就算是在这种情况下求出的钓鱼序列 为 1 ,5,6, 2, 3, 2,7 ,你可能会认为到了湖泊6之后再回到湖泊2可能要再花时间而且题目也不允许,但是这只是钓鱼序列,我们可以用 1 2 2 3 5 6 7 来实现这种钓鱼序列。
复杂度 O(n * n * h)


代码

#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define mep(i, a, b) for(int i = a; i < b; i++)
#define uep(i, a, b) for(int i = a; i >= b; i--)
#define cls(a, b) memset(a, b, sizeof(a))
int f[30], d[30], t[30];
int T, n, h, ks;
int maxtime, ans_time[30], fishtime;
int main(){
    ks = 0;
    scanf("%d", &T);
    while(T--){
        scanf("%d%d", &n, &h);
        rep(i, 1, n) scanf("%d", &f[i]);
        rep(i, 1, n) scanf("%d", &d[i]);
        mep(i, 1, n) scanf("%d", &t[i]);
        maxtime = 0;
        cls(ans_time, 0);
        rep(i, 1, n){ //枚举一下走过的湖泊数
            int tmpsum = 0, sum = 0;
            mep(j, 1, i){
                sum += t[j]*5;
            }
            fishtime = (h * 60 - sum) / 5; //剩下的捕鱼时间,这里面可以瞬间转移
            int curf[30], cur_ans_time[30];
            cls(cur_ans_time, 0);
            rep(j, 1, i) curf[j] = f[j];
            rep(j, 1, fishtime){
                int mxpos = 1;
                rep(k, 1, i){ //可以堆优化
                    if(curf[k] > curf[mxpos]){
                        mxpos = k;
                    }
                }
                tmpsum += curf[mxpos];
                curf[mxpos] -= d[mxpos];
                if(curf[mxpos] < 0){
                    curf[mxpos] = 0;
                }
                cur_ans_time[mxpos] += 5;
            }
            if(tmpsum > maxtime){
                rep(i, 1, n){
                    ans_time[i] = cur_ans_time[i];
                }
                maxtime = tmpsum;
            }
        }
        printf("Case %d:\n", ++ks);
        printf("%d", ans_time[1]);
        rep(i, 2, n){
            printf(", %d", ans_time[i]);
        }
        printf("\n");
        printf("Number of fish expected: %d\n", maxtime);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40513946/article/details/79990806
今日推荐