题目大意:有一道线性篱笆由N个连续的木板组成。有K个工人,你要叫他们给木板涂色。每个工人有3个参数:L 表示 这个工人可以涂的最大木板数目,S表示这个工人站在哪一块木板,P表示这个工人每涂一个木板可以得到的钱。要注意的是,工人i可以选择不涂任何木板,否则,他的涂色区域必须是连续的一段,并且S[i]必须包含在内。 最后还有,每块木板只能被涂一次。   状态方程比较容易想:dp[i][j]表示第i个人刷的最后一面墙是j时的最大获利,则 dp[i][j]=max(dp[i-1][k]+(j-k)*p[i]) j-l[i]+1<=k+1<=s[i]         (*) dp[i][j]=max(dp[i-1][j],dp[i][j-1],dp[i][j])//第i个人不刷,第j面墙不刷   但是O(k*n^2)的复杂度显然不能接受。而针对(*)这种“特殊”的转移方程,我们可以用单调队列把它优化到O(1): dp[i][j]=max(dp[i-1][k]-k*p[i])+j*p[i] 其中j*p[i]在i,j两重循环中相当于常数,所以,对于状态dp[i][j]只要单调队列维护dp[i-1][k]-k*p[i]的最大值即可   单调队列维护过程(可以回过头看看POJ 2823---单调队列的模型): 单调队列具体的做法是:最外层循环为i,首先把j=1~s[i]-1转移完(因为它不涉及第三个转移),然后把(j-l[i]<=k<=s[i]-1)的决策点的F[i-1,k]-p[i]*k依次入队建立“入队早晚时间递增,F[i-1,k]-p[i]*k的值递减”的单调队列,接下来循环j=s[i]~s[i]+l[i]-1,进行这三个转移(第三个转移只需要用队首元素),其中每次需要把队首超出长度限制的决策点出队;最后把剩下的到n循环完,只需要前两个转移。


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MID(x,y) ((x+y)>>1)
using namespace std;
typedef long long LL;
struct worker{int l, p, s;
}w[105];
bool cmp(worker a, worker b){return a.s < b.s;
}
int f[105][16005];
int n,k;
void debug(){for (int i = 0; i <= k; i ++){for (int j = 0; j <= n; j ++)printf("%d %d %d\n", i, j, f[i][j]);}
}
deque  Q;
void initQ(){while(!Q.empty())Q.pop_back();
}
int main(){scanf("%d %d", &n, &k);for (int i = 1; i <= k; i ++)scanf("%d %d %d", &w[i].l, &w[i].p, &w[i].s);sort(w+1, w+k+1, cmp);  //别忘了先按S排序!for (int i = 1; i <= k; i ++){for (int j = 0; j < w[i].s; j ++)f[i][j] = max(f[i-1][j], f[i][j-1]);//单调队列initQ();for (int j = max(0, w[i].s - w[i].l); j < w[i].s; j ++){while(!Q.empty() && f[i-1][Q.back()] - Q.back()*w[i].p <= f[i-1][j] - j*w[i].p)Q.pop_back();Q.push_back(j);}for (int j = w[i].s; j < min(w[i].s + w[i].l, n+1); j ++){while (!Q.empty() && Q.front() < j - w[i].l)Q.pop_front();f[i][j] = max(f[i-1][j], f[i][j-1]);f[i][j] = max(f[i][j], f[i-1][Q.front()] - Q.front()*w[i].p + j * w[i].p);
//            朴素DP:
//            for (int p = max(0, j - w[i].l); p <= j; p ++)
//                f[i][j] = max(f[i][j], f[i-1][p] + (j - p)*w[i].p);}for (int j = w[i].s + w[i].l; j <=n; j ++)f[i][j] = max(f[i-1][j], f[i][j-1]);}debug();int res = 0;for (int j = 1; j <= n; j ++)res = max(res, f[k][j]);printf("%d\n", res);return 0;
}

转载于:https://www.cnblogs.com/AbandonZHANG/archive/2013/02/21/4114223.html

POJ 1821 Fence ★(单调队列优化DP)相关推荐

  1. POJ 1821 Fence(单调队列优化DP)

    题解 以前做过很多单调队列优化DP的题. 这个题有一点不同是对于有的状态可以转移,有的状态不能转移. 然后一堆边界和注意点.导致写起来就很难受. 然后状态也比较难定义. dp[i][j]代表前i个人涂 ...

  2. POJ - 3926 Parade(单调队列优化dp)

    题目链接:点击查看 题目大意:给出一个n*m的街道,其中有(n+1)*m条街道,每条街道都有一个值,现在我们需要从最下面的任意一点出发,到达最上面的任意一点结束,问如何规划路线能让沿途经过的街道的权值 ...

  3. poj 1821(单调队列优化dp)

    题意:有一道线性篱笆由N个连续的木板组成.有K个工人,你要叫他们给木板涂色.每个工人有3个参数:L 表示 这个工人可以涂的最大木板数目,S表示这个工人站在哪一块木板,P表示这个工人每涂一个木板可以得到 ...

  4. poj 2373(单调队列优化dp)

    在长为L(<=1000000)的草地(可看成线段)上装喷水头,喷射是以这个喷水头为中心,喷水头的喷洒半径是可调节的调节范围为[a,b].要求草地的每个点被且只被一个喷水头覆盖,并且有些连续区间必 ...

  5. 算法笔记--单调队列优化dp

    单调队列:队列中元素单调递增或递减,可以用双端队列实现(deque),队列的前面和后面都可以入队出队. 单调队列优化dp: 问题引入: dp[i] = min( a[j] ) ,i-m < j ...

  6. 洛谷P3195 [HNOI2008]玩具装箱TOY(单调队列优化DP)

    题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...

  7. 【计蒜客 - 蓝桥训练】蒜厂年会(单调队列优化dp,循环数列的最大子段和)

    题干: 在蒜厂年会上有一个抽奖,在一个环形的桌子上,有 nn 个纸团,每个纸团上写一个数字,表示你可以获得多少蒜币.但是这个游戏比较坑,里面竟然有负数,表示你要支付多少蒜币.因为这些数字都是可见的,所 ...

  8. 单调队列以及单调队列优化DP

    单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...

  9. 【单调队列优化DP】烽火传递 LibreOJ - 10180

    题目来源 点我进入提交题目 反思 因为目前在学习单调队列优化DP,所以会往单调队列上面想.然后犯了一个错误就是,认为这个题目只要用单调队列就可以完成,单调队列只是用来减少时间复杂度的,遇到了求最优解的 ...

最新文章

  1. ucos-iii串口用信号量及环形队列中断发送,用内建消息队列中断接收
  2. 用perl获取可用的代理服务器地址
  3. PyQt5 技巧篇-便于文字排版的等宽字体推荐:Source Code Pro的中文为英文两倍宽字体
  4. 转:UNITY,如何为你的游戏选择正确的网络类型
  5. Oxite移植到ASP.NET MVC2 BETA 笔记(关于Html.RenderPartialFromSkin)
  6. 解决fullgc_「OOM」Java heap space原因与解决
  7. 第三次学JAVA再学不好就吃翔(part39)--package关键字
  8. NET问答: 多个 await 和 Task.WaitAll 是等价的吗?
  9. Cron, PAM, OpenDNS 介绍
  10. linux 从github拉取更新_2020年的GitHub年度报告,我看出了这些不一样的点
  11. [iOS]delegate和protocol
  12. 本博客自排名1000到400的各项数据变化
  13. vos3000下载java_昆石VOS3000_2.1.4.0完整安装包及安装脚本
  14. 关于高校通过ipv6免收费上网
  15. OWT在企业远程智能视频服务场景中的应用
  16. 毕业设计 - 基于人工智能的图像分类算法研究与实现 - 深度学习卷积神经网络图像分类
  17. IT职场: 选择外企利与弊
  18. Java8 ConcurrentHashMap的get()方法真的不需要加锁吗?
  19. C语言中的void*是什么?
  20. c语言设计生命游戏,C语言实现生命游戏.doc

热门文章

  1. 基于Continuous Conditional Neural Fields for Structured Regression的人脸特征点检测和头部姿态估计
  2. css实现圆形钟表,js+css3圆形指针时钟代码
  3. webpack4.0 babel配置遇到的问题
  4. Python 爬虫系列:糗事百科最热段子
  5. mysql 主从单库单表同步 binlog-do-db replicate-do-db
  6. HDU——2064汉诺塔III
  7. ubuntu下virtualbox使用u盘
  8. RAC分解步骤之一,在oracle linux 4u4上安装oracle 10.2.0.1.0操作日志
  9. android转IOS开发学习计划
  10. EJB(四)JPA 分布式事务处理