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;
    }
  • 相关阅读:
    Winpcap网络开发库入门
    主机字节序与网络字节序的转换
    WORD与DWORD
    TCP/IP各种数据包结构体
    解析IPV4报文 和IPV6 报文的 checksum
    TCP头校验和计算算法详解
    第九次作业:DFA最小化,语法分析初步
    第八次作业:非确定的自动机NFA确定化为DFA
    第七次:正规式、正规文法与自动机
    第六次作业:正规文法与正规式
  • 原文地址:https://www.cnblogs.com/longdouhzt/p/2118970.html
Copyright © 2011-2022 走看看