zoukankan      html  css  js  c++  java
  • poj1042 Gone Fishing **

    /*  贪心+优先级队列
    *
    * 贪心:为了不讨论在路上花费的时间,可以枚举到过的湖:比如:totLake=j 表示 到过湖1、2、..、j 相应的, 花在路上的时间
    * 就是 t[1]+t[2]+..+t[j-1] (显然每段路只会走一次) 于是算出leftTime,表示花在钓鱼上的时间
    * 这样一来,就不同再考虑路上的时间了,可以认为John有瞬间移动,哪个湖鱼多,就到哪个湖钓(当然 湖的编号 满足 1 <= ~ <=totLake )
    *
    * 于是可以用一个优先级队列,每次到与最多的湖钓,
    * 还要注意的是,如果某时刻有多个湖有同样多的鱼,则到湖编号最小的那个湖里钓!!(只要对优先级队列做相应的修改)
    * 用二叉堆实现优先级队列
    *
    * 最后注意ans == 0的情况
    * 看数据:
    * 2
    * 1
    * 0 0
    * 1 1
    * 1
    * 答案:
    * 60 0
    * 0
    */

    #include
    <cstdio>
    #include
    <cstring>
    using namespace std;

    const int maxN = 25 + 2, inf = 100000;
    int n, h, f[maxN], d[maxN], t[maxN]; //如题所述
    int timeOnLake[maxN], totLake, ans, ansTimeOnLake[maxN];

    int heap[maxN], key[maxN]; //heap【】:该节点的湖编号。。key【】:该节点当前的能钓到的鱼数


    void ini(){
    for(int i=1; i<=totLake; i++){
    heap[i]
    = i; key[i] = f[i];
    }
    memset(timeOnLake,
    0, sizeof(timeOnLake));
    }

    int inline left(int i){ return i*2; }
    int inline right(int i){ return i*2+1; }
    int inline p(int i){ return i/2; }

    void inline swap(int x, int y){
    int tmp;
    tmp
    = heap[x]; heap[x] = heap[y]; heap[y] = tmp;
    tmp
    = key[x]; key[x] = key[y]; key[y] = tmp;
    }

    void max_heapify(int i, int tot){
    int imax = i;
    int l = left(i);
    int r = right(i);

    //注意做相应的修改。。key相同时,湖编号小的优先级高
    if(l <= tot && (key[l] > key[imax] || (key[l]==key[imax] && heap[l] < heap[imax])))
    imax
    = l;
    if(r <= tot && (key[r] > key[imax] || (key[r]==key[imax] && heap[r] < heap[imax])))
    imax
    = r;

    if(imax != i){
    swap(i, imax);
    max_heapify(imax, tot);
    }
    }
    //建堆
    void build_max_heap(){
    for(int i=totLake/2; i>=1; i--){
    max_heapify(i, totLake);
    }
    }
    //弹出最大元
    int heap_extract_max(int &lakeNum, int &tot){
    lakeNum
    = heap[1];
    int maxKey = key[1];

    swap(
    1, tot);
    tot
    --;
    max_heapify(
    1, tot);
    return maxKey;
    }
    //把i节点的key增加到newKey
    void heap_increase_key(int i, int newKey){
    key[i]
    = newKey;
    //注意这里也要有相应的修改
    while(i>1 && (key[p(i)]<key[i] || (key[p(i)]==key[i] && heap[p(i)]>heap[i]))){
    swap(i, p(i));
    i
    = p(i);
    }
    }
    //插入key为newKey的节点
    void max_heap_insert(int newNode, int &tot){
    tot
    ++;
    key[tot]
    = -inf;
    heap_increase_key(tot, newNode);
    }

    //函数
    void fish(int timeLeft){
    build_max_heap();

    int tmp_ans = 0;
    while(timeLeft){
    int lakeNum, tot = totLake;
    int maxFish = heap_extract_max(lakeNum, tot);

    if(maxFish == 0){ //没鱼可钓了,直接在1号湖加上timeLeft
    timeOnLake[1] += timeLeft; break;
    }

    tmp_ans
    += maxFish;
    timeOnLake[lakeNum]
    ++;

    int newfish = (maxFish-d[lakeNum]<0 ? 0 : maxFish-d[lakeNum]);
    max_heap_insert(newfish, tot);

    timeLeft
    --;
    }

    if(tmp_ans > ans){
    ans
    = tmp_ans;
    memcpy(ansTimeOnLake, timeOnLake,
    sizeof(ansTimeOnLake));
    }
    }



    int main(){
    while(scanf("%d", &n)){
    if(n == 0)
    return 0;

    scanf(
    "%d", &h);
    h
    = h * 60 / 5; //改为以5分钟为单位
    for(int i=1; i<=n; i++)
    scanf(
    "%d", &f[i]);
    for(int i=1; i<=n; i++)
    scanf(
    "%d", &d[i]);
    for(int i=1; i<n; i++)
    scanf(
    "%d", &t[i]);
    t[
    0] = 0;


    ans
    = 0;
    int timeOnRoad = 0;
    for(totLake=1; totLake<=n; totLake++){
    timeOnRoad
    += t[totLake-1];
    if(timeOnRoad > h) break;

    ini();
    int timeLeft = h - timeOnRoad;
    fish(timeLeft);
    }

    //注意ans==0的情况!!
    if(ans == 0){
    printf(
    "%d", h*5);
    for(int i=2; i<=n; i++)
    printf(
    ", %d", 0);
    printf(
    "\nNumber of fish expected: %d\n\n", ans);
    }
    else{
    for(int i=1; i<n; i++)
    printf(
    "%d, ", ansTimeOnLake[i]*5);
    printf(
    "%d\n", ansTimeOnLake[n]*5);
    printf(
    "Number of fish expected: %d\n\n", ans);
    }
    }

    return 0;
    }
  • 相关阅读:
    优化SQL查询:如何写出高性能SQL语句
    提高SQL执行效率的16种方法
    Spring Ioc DI 原理
    java内存泄漏
    转:js闭包
    LeetCode Best Time to Buy and Sell Stock III
    LeetCode Best Time to Buy and Sell Stock with Cooldown
    LeetCode Length of Longest Fibonacci Subsequence
    LeetCode Divisor Game
    LeetCode Sum of Even Numbers After Queries
  • 原文地址:https://www.cnblogs.com/longdouhzt/p/2118970.html
Copyright © 2011-2022 走看看