题意:n个墙壁m个粉刷匠,每个墙壁至多能被刷一次,每个粉刷匠要么不刷,要么就粉刷包含第Si块的长度不超过Li的连续墙壁(中间可不刷),每一块被刷的墙壁都可获得Pi的利润,求最大利润

避免重复粉刷:

首先对Si排序并定义\(f[i][j]\):前i个木匠处理到第j块木板时的最大利润

此时[j+1,n]保证没被处理以满足无后效性

保证情况一的合法

\(f[i][j]=f[i-1][j]\)

保证情况二的Si必须被粉刷

定义处理的区间为[k+1,j]

则\(f[i][j]=max_kf[i-1][k]+P_i*(j-k)\)

此时要求Si必须在[k+1,j]内部,则对k加以限定:\(k+1≤S_i≤j\)

连续长度的表示:\(j-k≤L_i\)

中间可空出部分的表示\(f[i][j]=f[i][j-1]\)

由此可总结转移方程的三部分

前两部分为 \(f[i][j]=max(f[i-1][j],f[i][j-1])\)

最后一部分为\(f[i][j]=max_{j-L_i≤k≤S_i-1}f[i-1][k]+P_i*(j-k),S_i≤j\)

对于第三部分可改写方程为\(f[i][j]=max_{j-L_i≤k≤S_i-1}(f[i-1][k]-k*P_i)+j*P_i,S_i≤j\)以满足单调队列优化

单调队列在\(i\)的内循环当中可认为\(i\)是常数,也就是说每一层\(i\)都需要设立一个只与\(k\)有关的单调队列\(que\),但在实际中只使用一个

\(que\)每一次的初始化范围由最小的\(j\)决定

由\(S_i≤j\)和\(j-L_i≤k≤S_i-1\)

得\(S_i-L_i≤k_{init}≤S_i-1\)

此时\(j=1\)则得到所有有效的状态\(k\)

更新过程保证头部\(val\)最优,\(k\)单调递增(因为后者的更新顺序是从左往右)

注意单调更新时只对头部更新,因为单调范围右边界总是\(S_i-1\)

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define erep(i,u) for(register int i=head[u];~i;i=nxt[i])
#define iter(i,j) for(int i=0;i<(j).size();i++)
#define print(a) printf("%lld",(ll)a)
#define println(a) printf("%lld\n",(ll)a)
#define printbk(a) printf("%lld ",(ll)a)
#define IOS ios::sync_with_stdio(0)
using namespace std;
const int MAXN = 2e4+11;
const int oo = 0x3f3f3f3f;
typedef long long ll;
ll read(){
ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
struct XJB{
int l,p,s;
bool operator < (const XJB &r) const{
return s<r.s;
}
}a[MAXN];
int n,m;
int f[233][MAXN];
inline int cal(int i,int k){
return f[i-1][k]-a[i].p*k;
}
int main(){
while(cin>>n>>m){
rep(i,1,m){
a[i].l=read();
a[i].p=read();
a[i].s=read();
}
sort(a+1,a+1+m);
memset(f,0,sizeof f);
deque<int> que;
rep(i,1,m){
while(!que.empty()) que.pop_back();
rep(k,max(0,a[i].s-a[i].l),a[i].s-1){ //j-Li<=k<=Si-1,j>=Si
while(!que.empty()&&cal(i,k)>=cal(i,que.back())) que.pop_back();
que.push_back(k);
}
rep(j,1,n){
f[i][j]=max(f[i-1][j],f[i][j-1]);
if(j>=a[i].s){
while(!que.empty()&&que.front()<j-a[i].l) que.pop_front();
if(!que.empty()) f[i][j]=max(f[i][j],cal(i,que.front())+a[i].p*j);
}
}
}
println(f[m][n]);
}
return 0;
}

POJ - 1821 单调队列优化DP + 部分笔记的更多相关文章

  1. 【笔记篇】单调队列优化dp学习笔记&&luogu2569_bzoj1855股票交♂易

    DP颂 DP之神 圣洁美丽 算法光芒照大地 我们怀着 崇高敬意 跪倒在DP神殿里 你的复杂 能让蒟蒻 试图入门却放弃 在你光辉 照耀下面 AC真心不容易 dp大概是最经久不衰 亘古不化的算法了吧. 而 ...

  2. POJ 2373 单调队列优化DP

    题意: 思路: f[i] = min(f[j]) + 1; 2 * a <= i - j <= 2 *b: i表示当前在第i个点.f[i]表示当前最少的线段个数 先是N^2的朴素DP(果断 ...

  3. poj 1821 Fence 单调队列优化dp

    /* poj 1821 n*n*m 暴力*/ #include<iostream> #include<cstdio> #include<cstring> #incl ...

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

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

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

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

  6. 「学习笔记」单调队列优化dp

    目录 算法 例题 最大子段和 题意 思路 代码 修剪草坪 题意 思路 代码 瑰丽华尔兹 题意 思路 代码 股票交易 题意 思路 代码 算法 使用单调队列优化dp 废话 对与一些dp的转移方程,我们可以 ...

  7. 单调队列优化DP——习题收集

    前言 感觉可以用单调队列优化dp的模型还是挺活的,开个随笔记录一些遇到的比较有代表性的模型,断续更新.主要做一个收集整理总结工作. 记录 0x01 POJ - 1821 Fence,比较适合入门的题, ...

  8. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

  9. bzoj1855: [Scoi2010]股票交易--单调队列优化DP

    单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...

随机推荐

  1. [Token] 从index.jsp中获取Token

    import com.eviware.soapui.support.GroovyUtils def groovyUtils = new GroovyUtils( context ) def holde ...

  2. 搭建自己的MQTT服务器

    搭建自己的MQTT服务器 物联网电子世界 百家号08-2903:04 MQTT协议是广泛应用的物联网协议,使用测试MQTT协议需要MQTT的代理.有两种方法使用MQTT服务,一是租用现成的MQTT服务 ...

  3. CoderForces 518D Ilya and Escalator (期望DP)

    题意:给定 n 个人,在每一时刻一个人进入地铁的概率是 p,站着不动的概率是 1-p,然后问你 t 时间地铁里有多少人. 析:很明显这是一个期望DP,用d[i][j]表示 i 时刻 j 个人进入地铁的 ...

  4. Android-相对布局(RelativeLayout)

    <?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android=&qu ...

  5. mybatis 基础教程

    1.引用mybatis.jar包,以后依赖包. 2.配置映射文件(一个是主配置文件,一个是sql映射文件),注意,mapper.xml 文件必须和dao放在一起. 3.mybatis.xml文件说明 ...

  6. mybatis--mapper配置总结

    mapper介绍 mapper使用规则:按业务划分,一个业务模块相关的sql均定义在一个mapper文件 mapper的xml格式: doctype: <!DOCTYPE mapper PUBL ...

  7. 关于Relay的麻烦之处

    问题背景 由于QueryRender是直接将数据塞进Render()里的 handleUpdate = (hasNextPage, xdata) =>{ console.log(3); cons ...

  8. 萌新web前端从零开始(1)——计算机入门

    前言:这是一个萌新从零开始的学习之路,与大家分享自己的看法与见解,还请指出错误与遗漏点方便改正. 1.认识计算机. 计算机语言常见的有C,PHP,Ruby,Java,C#,Basic,JS,C++等, ...

  9. C# 连接 IBM MQ

    安装 IBM WebSphere MQ:http://www-01.ibm.com/software/integration/wmq/explorer/downloads/ 正确安装要注意几个地方,集 ...

  10. leetcode 字符串中的第一个唯一字符

    给定一个字符串,找到它的第一个不重复的字符,并返回它的索引.如果不存在,则返回 -1. 案例: s = "leetcode" 返回 0. s = "loveleetcod ...