poj 1821 Fence(单调队列优化DP)
poj 1821 Fence


$ solution: $
这道题因为每一个粉刷的人都有一块“必刷的木板”,所以可以预见我们的最终方案里的粉刷匠一定是按其必刷的木板的顺序排列的。这就提示了我们可以用线性 $ DP $ ,只需要将粉刷匠按必刷的木板排序即可。
设 $ F[ $ i $ ][j] $ 表示前 $ i $ 个粉刷匠刷了前 $ j $ 快木板的最大收益(可以有木板不刷!)。我们可以根据题意列出转移方程:
- 首先这个粉刷匠一块木板也不刷
- 这块木板不刷
- 这个粉刷匠从第k块木板刷到第 $ j $ 块木板(这个有限制)
于是我们列出方程:
$ F[i][j]=max{F[i-1][j],\quad F[i][j-1],\quad ^{\quad max}_{j-L_i\leq k< S_i}{F[i-1][k]+P_i\times (j-k) } } $
然后我们发现前两个都好转移,但最后一个需要枚举耗费大量时间,而我们的数据范围就很不友好了。于是我们考虑如何优化:首先先将与k无关的项提取出来,这个可以直接放外面。
$ F[i][j]=^{\quad max}_{j-L_i\leq k< S_i}{F[i-1][k]-P_i\times k }+P_i\times j $
然后我们发现现在 $ max $ 函数里面的东西基本只和k有关, $ i $ 在循环枚举的外围可以相当于定值,于是我们可以用一个单调队列维护 $ F[i-1][k]-P_i\times k $ 这个东西,我们不能直接更新最大值,因为 $ j-L_i\leq k< S_i $ 会使我们之前的最大值失效,所以我们的单调队列需要满足双向删除,取队头(对头就是最优决策)。
总复杂度 $ O(N\times M) $
$ code: $
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define ll long long
#define db double
#define inf 0x7fffffff
#define rg register int
using namespace std;
int n,m;
int b[16005];
int q[16005];
int f[105][16005];
struct su{
int l,s,v;
inline bool operator <(su x){
return s<x.s;
}
}a[105];
inline int ff(int i,int j){
return f[i-1][j]-a[i].v*j;
}
inline int qr(){
register char ch; register bool sign=0; rg res=0;
while(!isdigit(ch=getchar())) if(ch=='-')sign=1;
while(isdigit(ch)) res=res*10+(ch^48),ch=getchar();
return sign?-res:res;
}
int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
m=qr(); n=qr();
for(rg i=1;i<=n;++i){
a[i].l=qr(); a[i].v=qr(); a[i].s=qr();
} sort(a+1,a+n+1);
for(rg i=1;i<=n;++i){ rg l=1,r=0;
for(rg j=max(0,a[i].s-a[i].l);j<a[i].s;++j){
while(l<=r&&ff(i,j)>=ff(i,q[r]))--r;; q[++r]=j;
}
for(rg j=1;j<=m;++j){
f[i][j]=max(f[i-1][j],f[i][j-1]);
if(j>=a[i].s){
while(l<=r&&q[l]<j-a[i].l)++l;
if(l<=r)f[i][j]=max(f[i][j],ff(i,q[l])+a[i].v*j);
}
}
}printf("%d\n",f[n][m]);
return 0;
}
poj 1821 Fence(单调队列优化DP)的更多相关文章
- POJ 1821 Fence(单调队列优化DP)
题解 以前做过很多单调队列优化DP的题. 这个题有一点不同是对于有的状态可以转移,有的状态不能转移. 然后一堆边界和注意点.导致写起来就很难受. 然后状态也比较难定义. dp[i][j]代表前i个人涂 ...
- poj 1821 Fence 单调队列优化dp
/* poj 1821 n*n*m 暴力*/ #include<iostream> #include<cstdio> #include<cstring> #incl ...
- $Poj1821\ Fence\ $单调队列优化$DP$
Poj Acwing Description 有N块木板等待被M个工匠粉刷,每块木板至多被刷一次.第i个工匠要么不粉刷,要么粉刷包含木块Si的,长度不超过Li的连续的一段木板,每粉刷一块可以得到P ...
- Dividing the Path POJ - 2373(单调队列优化dp)
给出一个n长度的区间,然后有一些小区间只能被喷水一次,其他区间可以喷水多次,然后问你要把这个区间覆盖起来最小需要多少喷头,喷头的半径是[a, b]. 对于每个只能覆盖一次的区间,我们可以把他中间的部分 ...
- poj1821 Fence(单调队列优化dp)
地址 一排N个木板,M个工匠站在不同位置$S_i$,每个人可以粉刷覆盖他位置的.最长长度为$L_i$木板段,每刷一个有$P_i$报酬.同一木板只刷一次.求最大报酬. 根据每个人的位置dp,设$f[i] ...
- 单调队列优化DP——习题收集
前言 感觉可以用单调队列优化dp的模型还是挺活的,开个随笔记录一些遇到的比较有代表性的模型,断续更新.主要做一个收集整理总结工作. 记录 0x01 POJ - 1821 Fence,比较适合入门的题, ...
- 算法笔记--单调队列优化dp
单调队列:队列中元素单调递增或递减,可以用双端队列实现(deque),队列的前面和后面都可以入队出队. 单调队列优化dp: 问题引入: dp[i] = min( a[j] ) ,i-m < j ...
- 单调队列优化DP,多重背包
单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...
- 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 ...
- hdu3401:单调队列优化dp
第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...
随机推荐
- 【Luogu】P1383高级打字机
可持久化线段树模板题之一. 权当温习主席树模板 #include<cstdio> #include<cstdlib> #include<cctype> #defin ...
- poj3180 The Cow Prom
The Cow Prom Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2373 Accepted: 1402 Desc ...
- 垃圾收集器与内存分配策略 (深入理解JVM二)
1.概述 垃圾收集(Garbage Collection,GC). 当需要排查各种内存溢出.内存泄露问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,我们就需要对这些“自动化”的技术实施必要的监控和调 ...
- spl_autoload_register() && __autoload函数
一.__autoload 这是一个自动加载函数,在PHP5中,当我们实例化一个未定义的类时,就会触发此函数. 在index.php中,由于没有包含test.class.php,在实例化printit时 ...
- android的网络访问URL
Thread visitBaiduThread = new Thread(new VisitWebRunnable()); visitBaiduThread.start(); try ...
- VM虚拟机
VMWare提供了三种工作模式,它们是bridged(桥接模式).NAT(网络地址转换模式)和host-only(主机模式).要想在网络管理和维护中合理应用它们,你就应该先了解一下这三种工作模式. 1 ...
- (5)Swing事件
import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; publi ...
- Java_AOP原理
AOP : 面向切面编程 在程序设计中,我们需要满足高耦合低内聚,所以编程需满足六大原则,一个法则. AOP面向切面编程正是为了满足这些原则的一种编程思想. 一.装饰者模式: 当我们需要给对象增加功能 ...
- codevs——1958 刺激
1958 刺激 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description saffah的一个朋友S酷爱滑雪,并且追求刺 ...
- java基础之IO流(二)之字符流
java基础之IO流(二)之字符流 字符流,顾名思义,它是以字符为数据处理单元的流对象,那么字符流和字节流之间的关系又是如何呢? 字符流可以理解为是字节流+字符编码集额一种封装与抽象,专门设计用来读写 ...