其他分享
首页 > 其他分享> > 4.15题型总结

4.15题型总结

作者:互联网

1.采药&4.开心的金明

我想把这2题放在一起来说,因为都和背包DP很像。

(应该没什么多的知识点)

用时大概每题8分钟。

 

2.钓鱼

这个题我一开始按照背包的模板来做,即两种向下推的方式

f[i][j]表示在i号池塘第j分钟钓到鱼的最大值

则f[i][j] = max(f[i-1][j-nxt[i-1]] , f[i][j-st]+num(i,st)) 其中st为上一个取左边的对应j的值,num(i,st)就是从st到j这段时间i池塘能钓到的鱼。

这是初步结论,但是打完以后并不能得到正确答案,于是考虑替换。

对于每个F[i][n] 参考上面,i不变时,影响它的只有f[i][...]取的次数,那么每取一次更新一次,DP就可以按照每次取最大鱼的顺序来。

如果只看第1,2号池塘,按取最大鱼的顺序,要先把1,2号池塘第一分钟的情况进入单调队列,然后在时间用尽或鱼跑尽之前,不断取钓到鱼最多的情况(队首)

还要注意,因为可以停在任何一个池塘不往下走,所以外面的循环是(i,1,n)(j,1,i)

    FOR(i,1,n){
        /*FOR(j,snxt[i-1],T){
            int k = j-st;
            int plu = k*num[i]-(k-1)*decr[i];
            if(f[i-1][j-nxt[i-1]] > f[i][k] + plu){
                st = j;
                f[i][j] = f[i-1][j-nxt[i-1]];
                //printf("cross  ");
            }
            else f[i][j] = f[i][k] + plu;
            //printf("%d %d:%d,%d,%d\n",i,j,st,k,f[i][j]);
        }*/
        int j = 1,k = T;
        while(!q.empty()) q.pop();
        FOR(j,1,i) q.push(make_pair(num[j],j));
        while(k > 0 && q.top().first > 0){ //时间用尽;鱼跑尽; 
            pair<int,int> w = q.top();q.pop();
            tmp += w.first;
            q.push(make_pair(w.first-decr[w.second] , w.second));
            k--;
        }
        ans = max(ans,tmp);
        tmp = 0;
        T-= nxt[i];
    }

前期用时40分钟左右,后期改用时30分钟。

3.铲雪

一开始是被这个题懵住了,以为要很高级的算法。(涉及到算交叉点以及DP什么的)

不过至少知道铲雪的路等于总路程,可以减少一半的考虑复杂度。

然后听同学说就知道了,也不需要写递推,而是推数学表达式(我一开始一直以为要递推)

又借鉴了一下同学,这样才推出来

这个题告诉我们,读完题自觉有难度而退缩,不如把他想象成一个水题来做。

 

标签:总结,题型,plu,4.15,nxt,st,num,池塘,tmp
来源: https://www.cnblogs.com/y1nfelix/p/16147571.html