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股 且一次 ...
随机推荐
- 【容器人必看】你一定要来 ECUG Con 2018 的三个理由!
引领国内云领域风向的高端峰会 ECUG Con 2018,即将在 12 月 22-23 日 深圳南山 全新启程!如果你的工作和容器内容相关联,如果你的兴趣和容器技术有交集,如果你是「容器人」,那么这就 ...
- 【Luogu】P3052摩天大楼里的奶牛(状压DP)
参见ZHT467的题解. f[i]表示在i这个集合下的最少分组数和当前组最少的容量. 从1到(1<<n)-1枚举i,对于每个i枚举它的子奶牛,然后重载运算符计算. 代码如下 #includ ...
- Opencv学习笔记——视频高斯模糊并分别输出
用两个窗口进行对比 #include "stdafx.h" #include <iostream> #include <opencv2/core/core.hpp ...
- JConsole手册
一篇Sun官方网站上介绍JConsole使用的文章,前段时间性能测试的时候大概翻译了一下以便学习,今天整理一下发上来,有些地方也不知道怎么翻,就保留了原文,可能还好理解点,呵呵,水平有限,翻的不好,大 ...
- 送外卖(codevs 2800)
题目描述 Description 有一个送外卖的,他手上有n份订单,他要把n份东西,分别送达n个不同的客户的手上.n个不同的客户分别在1~n个编号的城市中.送外卖的从0号城市出发,然后n个城市都要走一 ...
- 素数判定 2(codevs 1702)
题目描述 Description 一个数,他是素数么? 设他为P满足(P<=263-1) 输入描述 Input Description P 输出描述 Output Description Yes ...
- linux 抓取访问量排行
需求: 分析图片服务日志,把日志(每个图片访问次数*图片大小的总和)排行,取top10,也就是计算每个url的总访问大小 语句: awk '{a[$1]+=$10;}END{for(i in a){p ...
- 2014湘潭全国邀请赛I题 Intervals /POJ 3680 / 在限制次数下取有权区间使权最大/小问题(费用流)
先说POJ3680:给n个有权(权<10w)开区间(n<200),(区间最多数到10w)保证数轴上所有数最多被覆盖k次的情况下要求总权最大,输出最大权. 思路: 限制的处理:s ...
- eclipse 安卓虚拟机安装apk 及常见问题
首先必须启动虚拟机然后如图操作:
- Effective Java P2 Item1 Consider static factory methods instead of constructors
获得一个类的实例的传统方法是公共的构造方法,还可以提供一个公共的静态工厂方法(一个返回值为该类实例的简单静态方法), 例如Boolean(boolean 的封装类) public static Boo ...