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